Несовместимые типы в условном выражении при приведении
В настоящее время я работаю над упражнениями 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 ответа:
В описании условного оператора в стандарте C (6.5.15 условный оператор) записано:
3 для второго и третьего операндов выполняется одно из следующих условий: - оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимые типы;
Совместимые функции должны иметь совместимые параметры.
Поскольку ваши функции имеют указатели в качестве параметров, то
2 для совместимости двух типов указателей, оба должно быть одинаково квалифицированные и оба должны быть указателями на совместимые типы.
Однако параметры этих двух функций не являются идентичными.
Таким образом, компилятор прав.
Ваша ошибка заключается в использовании плохого прототипа для вашей пользовательской функции сравнения
numcmp
.
Он должен принимать указатели наconst
:Условный оператор не может принимать аргументы 2 и 3, где ни один из них не может быть неявно преобразован в другой тип, но вы можете естественным образом привести их к тому же типу заранее.int numcmp(char const *s1, const char *s2); // Showing both equivalent orders for const