In the K&R ANSI C book I have stumbled upon a piece of code where a pointer to a function is used. I think I understand the idea behind pointers to functions, but the example presented in the book does not make sense to me.
The function is to sort lines of text using quicksort sorting algorithm. The declaration of quicksort function looks like this:
void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *);
This so far makes perfect sense to me, we are declaring a function where one of the arguments is a pointer to a function (comp) with two void pointer arguments. I assume we are doing it this way to save memory, and not make copies of actual function.
Later on the function is used in main in this way:
qsort((void **) lineptr, 0, nlines-1, (int (*)(void*, void*))(numeric ? numcmp : strcmp));
Here is where I have some questions:
lineptr
cast to (void **)(numeric ? numcmp : strcmp)
, does it mean that pointers to functions can also be assigned like this: int ( * )(void*, void*) numcmp
EDIT: The lineptr
is defined like this: char *lineptr[MAXLINES];
I assume we are casting void**
to change it from char to type void pointer
The K&R book predates standardized C, so some constructs which were valid at the time are no longer valid. Specifically, it seems to be assuming that conversion between any two pointer types is valid.
lineptr
is an array of char *
, and this array will decay into a pointer to its first element when used in an expression, i.e. char **
. So the cast to void **
is needed to match the argument type, as only a conversion to/from void *
may be performed without a cast.
The expression (numeric ? numcmp : strcmp)
is choosing a function to pass as the comp
parameter to the function, so either numcmp
or strcmp
depending on the value of numeric
. The cast to (int (*)(void*, void*))
is needed because strcmp
(and presumably numcmp
) has type int (*)(const char *, const char *)
.
Casting to a different function pointer type and subsequently calling the function using the casted type is undefined behavior in standard C, however it was probably allowed in K&R C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With