4 ms·
C11 added (limited) generic support
by kevin_thibedeau 3y ago
C11 added (limited) generic support
- remexre 3y agoYou can't specialize a generic algorithm for specific operations and data structures; in C++ terms, it gives you overloading, not templates.
- kevin_thibedeau 3y agoIt gives generic programming. C++ templates aren't the only possible implementation.
- kaba0 3y agoSo where is a generic vector data structure written in plain C that is efficient (that is, doesn’t store pointers to elements).
- zrm 3y agoThey used "_Generic" as a keyword but it doesn't really do that. Suppose I need to define a copy assignment operator for the library's sort function to use. Is there a good way to overload it? Can the library know what the size of each element is based on its type without having to pass it in as a parameter? You can pass function pointers to the library, but that quickly becomes awful. /* sort for basic integer types */ void lib_sort_u8(uint8_t *a, size_t count); void lib_sort_i8(int8_t *a, size_t count); void lib_sort_u16(uint16_t *a, size_t count); void lib_sort_i16(int16_t *a, size_t count); void lib_sort_u32(uint32_t *a, size_t count); void lib_sort_i32(int32_t *a, size_t count); void lib_sort_u64(uint64_t *a, size_t count); void lib_sort_i64(int64_t *a, size_t count); /* specify a comparator */ void lib_sort_comp(void *start, size_t nmemb, size_t size, int (*compar), const void *, const void *)); /* specify a comparator and an assignment operator */ void lib_sort_assign_comp(void *start, size_t nmemb, size_t size, void (*assign)(void *, const void *), int (*compar)(const void *, const void *)); /* specify a comparator, an assignment operator, and ... */ Or, you get one function that takes all of the arguments and have to define and pass in a bunch of function pointers and type size parameters that are each an opportunity for bugs or UB in order to sort a simple array of integers. If my type needs a custom assignment operator, I need each library I use to take that as an argument. One expects the function pointer to take the arguments in the order (src, dst), another as (dst, src), a third specifies the return value as int instead of void, a fourth takes the source argument as "void *" instead of "const void *" in case you want to implement move semantics and a fifth doesn't support custom assignment operators at all. It's no surprise that people prefer to avoid this.