Either cmp func seems to work; cant understand how an arg1 of type int* is being resolved in the case of qsort_cmp. As far as I can figure: int* is passed to qsort_cmp where it is changed to void*, then in return statement cast to struct s*. So far no problem, but then cast object is supposed to have a member called b, which its cast type does but its instance does not...
struct s { int a, b; };
int qsort_cmp(const void *r1, const void *r2) {
return ((struct s*) r1)->b - ((struct s*) r2)->b;
}
int bsearch_cmp(const void *key, const void *r2) {
return *(int*) key - ((struct s*) r2)->b;
}
/* themap is already qsorted */
int k = 'w'//hatever;
void *ret = bsearch(&k, themap, thenumber_ofelements, sizeof(one_element), qsort_cmp);
These comparison function are not interchangeable: one compares the
bfields of both arguments, the other compares anintpointed to directly by the first argument and thebfield of the structure pointed to by the second argument. They would be equivalent if theafield was used instead ofb, as theafield is at the beginning of the structure.Here is the specification:
Hence the first argument can be a pointer to an
intand the second a pointer to an array of structures, as long as the comparison function is consistent with thebsearchcalling schemeConversely, the comparison function used in
qsortis called with 2 pointers to elements of the array, so both are pointers tosstructures.Note however that subtracting 2
intvalues is not a reliable way to produce the comparison result as this subtraction can overflow for many values:INT_MIN - 1for example. A better method is this:Modern compilers generate branchless code for this: https://godbolt.org/z/sW3dn6