Overload resolution on extern "C" and "C++" version of qsort()/bsearch()
bsearch, c++, qsort
Solution
The `int (*compar)(const void*, const void*)` parameter has different types for the two different overloads. For the first overload, it's an `extern "C"` function pointer parameter. For the second overload, it's an `extern "C++"` function pointer parameter. Any function pointer you pass to `qsort` will already have some sort of linkage, and that is what gets used to determine which overload to call.
To quote the standard:
7.5 Linkage specifications [dcl.link]
All function types, function names with external linkage, and variable names with external linkage have a language linkage. [...] The default language linkage of all function types, function names, and variable names is C++ language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical.
In fact, I don't think the standard actually means to require that the two `qsort` overloads really do have different linkage. Unlike in C, user-provided declarations of standard library functions are not allowed; the relevant difference between them is the type of `compar`. They could have been declared as
extern "C" typedef int (*__compar_fnp_c)(const void *, const void *);
extern "C++" typedef int (*__compar_fnp_cxx)(const void *, const void *);
void qsort(void* base, size_t nmemb, size_t size, __compar_fnp_c compar);
void qsort(void* base, size_t nmemb, size_t size, __compar_fnp_cxx compar);
where it should be more obvious that `__compar_fnp_c` and `__compar_fnp_cxx` are different types. That said, the as-if rule doesn't allow this implementation, since it would break code that takes a pointer or reference to `qsort`.
Note that GCC, as well as some other compilers, don't implement this correctly, and don't treat linkage as part of the function pointer's type. On such implementations, only one version of `qsort` will have been made available, to prevent a conflict during overload resolution.
Problem
In C++, there are two versions of `qsort()` provided by the standard library: ``` extern "C" void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)); extern "C++" void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)); ``` `bsearch()` is about the same. My question is, how does overload resolution work when calling `qsort()`? Does it automatically link to the appropriate function based on the linkage type ("C" or "C++") of the function pointer passed as the last argument? Or the caller needs to specify explicitly with some sort of extra syntax? (Let's just put away the temptation to call `std::sort` for a second...)