Несовместимые типы в условном выражении при приведении


В настоящее время я работаю над упражнениями K&R, и есть что-то, что меня беспокоит.

У меня есть объявление функции qsort:

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

Согласно книге, я должен быть в состоянии использовать условное выражение для выбора функции сравнения. У меня есть два из них:

int numcmp(char *s1, char *s2)

И cstring

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

Вызов выглядит следующим образом:

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

И мой MS VS дает мне ошибку:

Error: operand types are incompatible

И все же, когда я делаю это, как:

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

Все есть ОК.

Является ли книга неправильной, или это просто идея В. С. о том, как это должно быть сделано?
2 2

2 ответа:

В описании условного оператора в стандарте C (6.5.15 условный оператор) записано:

3 для второго и третьего операндов выполняется одно из следующих условий: - оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимые типы;

Совместимые функции должны иметь совместимые параметры.

Поскольку ваши функции имеют указатели в качестве параметров, то

2 для совместимости двух типов указателей, оба должно быть одинаково квалифицированные и оба должны быть указателями на совместимые типы.

Однако параметры этих двух функций не являются идентичными.

Таким образом, компилятор прав.

Ваша ошибка заключается в использовании плохого прототипа для вашей пользовательской функции сравнения numcmp.
Он должен принимать указатели на const:

int numcmp(char const *s1, const char *s2); // Showing both equivalent orders for const
Условный оператор не может принимать аргументы 2 и 3, где ни один из них не может быть неявно преобразован в другой тип, но вы можете естественным образом привести их к тому же типу заранее.