It doesn't have templates/generics.
It doesn't have templates/generics.
curl_easy_option_by_name() is already up to 24 characters and there's only two "levels" in curl_easy_*.
Annoyance #2: There's no formal registrar for LIBNAME. This isn't a big deal for popular libraries, but it's a pain having to keep a locally-modified copy of a less popular dependency just because it shares its name with another less popular dependency.
Annoyance #3: LIBNAME_actual_function_name() is a pain to read and using either the preprocessor or static inlines to locally alias function names for the sake of readability is silly.
@2: Agree, although I don't recall this ever happening to me.
@3: Is it? How is libname::actual_function_name() much better?
I actually like to use libname__actual_function_name(), as it further separates "namespace" from function name (unless we need compatibility with C++, as IIRC it reserves all double underscores, not only at the beginning).
This is still the case in C11, Section 5.2.4.1. Did this change in the most recent standard?
> @2: Agree, although I don't recall this ever happening to me.
It happened to me once. I ran across a library from 1994 and another from the 2010s which shared a simple name like "libamc". I'll comb through my records later to figure out the actual name.
> @3: Is it? How is libname::actual_function_name() much better?
It's not, but I wasn't thinking of C++ specifically. (I don't know C++. I've somehow managed to avoid it in many years of writing C.)
I was thinking more like the file-local namespace clobbering offered by Python e.g., from LIBNAME import actual_function_name.
Well, no, it's still marked "just" obsolete. For it to be deprecated or removed there would need to be anybody caring about it enough to put some work. But since it doesn't affect vendors at all (they can just ignore) and users don't complain, it's just a forgotten "law" - still law, but a dead one.
> I was thinking more like the file-local namespace clobbering offered by Python e.g., from LIBNAME import actual_function_name.
Oh, that's... way more than just namespaces. Way more. That would require more fundamental changes and additions. C++ just added modules in C++20 (not sure how well those will catch on), but I don't think something like that is to be expected in C for feasible future.
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.