qsort parameters

qsort seems to accept as its last parameter: (1) a function; (2) the
address of a function; and (3) a function pointer. Therefore, why is (3) in
the declaration? Why not declare its last parameter as a regular function
(therefore (2) and (3) become derivative alternatives)?

DECLARATION OF QSORT

1
2
void qsort ( void * base, size_t num, size_t size,
             int ( * compar ) ( const void *, const void * ) );


CONTEXT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* qsort example */
#include <stdio.h>
#include <stdlib.h>

int values[] = { 40, 10, 100, 90, 20, 25 };

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int main ()
{
  int n;

  qsort (values, 6, sizeof(int), compare);
  for (n=0; n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}


(1)

1
2
3
4
5
6
int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

qsort (values, 6, sizeof(int), compare);


(2)

1
2
3
4
5
6
int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

qsort (values, 6, sizeof(int), &compare);


(3)

1
2
3
4
5
6
7
8
9
int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int (*compare_pointer)(const void *, const void *);
compare_pointer = compare;

qsort(values, 6, sizeof(int), compare_pointer); 


It takes a function pointer. 1, 2, and 3 are just different ways to construct a function pointer to call it with.
These declarations

1
2
3
4
5
void qsort ( void * base, size_t num, size_t size,
             int ( * compar ) ( const void *, const void * ) );

void qsort ( void * base, size_t num, size_t size,
             int compar ( const void *, const void * ) );


are equivalent.

If a function is declared in one of the above ways the name of a function passed as argument is implicitly converted to a pointer to the function.
So these calls

1
2
qsort (values, 6, sizeof(int), &compare);
qsort (values, 6, sizeof(int), compare);


are also equivalent to the declarations shown above.
Last edited on
PS: great C interview question if the candidate wrote the three-way compare function this way: why is it wrong to compare values of type int using subtraction? (or, softer, "propose a unit test for this function")
@Cubbi
PS: great C interview question if the candidate wrote the three-way compare function this way: why is it wrong to compare values of type int using subtraction? (or, softer, "propose a unit test for this function")


I think you mean two-complement arithmetic with integers. Something as

INT_MAX - INT_MIN
I'm not sure if this is what you were referring to (I'm obviously a
novice), but is your question related to nasty behavior that results from
subtracting unsigned / signed ints? I found this on Stack Overflow:

"Edit: Actually, I could be wrong about the undefined behavior part.
According to C language specification, the common part of the range of the
corresponding signed and unsigned integer type shall have identical
representation (implying, according to the footnote 31, "interchangeability
as arguments to functions"). So, the result of a - b expression is unsigned
1001 as described above, and unless I'm missing something, it is legal to
print this specific unsigned value with %d specifier, since it falls
withing the positive range of int. Printing (unsigned) INT_MAX + 1 with %d
would be undefined, but 1001u is fine."
Topic archived. No new replies allowed.