Search code examples
cpointerscastingconditional-operatorkernighan-and-ritchie

Incompatible types in conditional expression when casting


I'm currently working my way through the K&R exercises, and there's something that's bugging me.

I have the qsort function declaration:

void qsort(void *v[], int left, int right,
           int (*comp)(void *, void *));

According to the book, I should be able to use the conditional expression to choose the compare function. I've got two of those:

int numcmp(char *s1, char *s2)

and the cstring's

int strcmp(const char *s1, const char *s2);

The call looks like:

qsort((void **)lineptr, 0, nlines - 1,
            (int(*)(void *, void *))(numeric ? numcmp : strcmp));

And my MS VS gives me an error:

Error: operand types are incompatible

Yet, when I do it like:

qsort((void **)lineptr, 0, nlines - 1,
            (numeric ? (int(*)(void *, void *))numcmp : (int(*)(void *, void *))strcmp));

all is OK.

Is the book wrong, or is it just VS's idea of how it should be done?


Solution

  • In the description of the conditional operator in C Standard (6.5.15 Conditional operator) there is written:

    3 One of the following shall hold for the second and third operands: — both operands are pointers to qualified or unqualified versions of compatible types;

    Compatible functions shall have compatible parameters.

    As your functions have pointers as parameters then

    2 For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

    However the parameters of the two functions are not identically qualified.

    Thus the compiler is correct.