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
b
fields of both arguments, the other compares anint
pointed to directly by the first argument and theb
field of the structure pointed to by the second argument. They would be equivalent if thea
field was used instead ofb
, as thea
field is at the beginning of the structure.Here is the specification:
Hence the first argument can be a pointer to an
int
and the second a pointer to an array of structures, as long as the comparison function is consistent with thebsearch
calling schemeConversely, the comparison function used in
qsort
is called with 2 pointers to elements of the array, so both are pointers tos
structures.Note however that subtracting 2
int
values is not a reliable way to produce the comparison result as this subtraction can overflow for many values:INT_MIN - 1
for example. A better method is this:Modern compilers generate branchless code for this: https://godbolt.org/z/sW3dn6