2009-03-20 1 views
7

Можно создать дубликат:
Problem compiling K&R exampleУказатель предупреждения типа несоответствие, например, от K & R C

В последнее время я работал мой путь через язык программирования C помощью K & Р.

В разделе 5.11 они охватывают указатели на функции и после ввода в их примере - реализации quicksort, где мы предоставляем указатель на compari son, которую мы хотим использовать - я получаю предупреждение от компилятора: несоответствие типа указателя в условном выражении. (Мой компилятор GCC 4.0.1 на OS X 10.5.6)

Строка из примера, который вызывает предупреждение является:

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

Программа выполняется без segfaulting, но мне нравится smoosh каждое предупреждение Я могу или, по крайней мере, понять их причины.

Функция декларация numcmp выглядит следующим образом:

int numcmp(char *, char *); 

Но согласно страницы руководства, stcmp имеет эту подпись:

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

ли предупреждение просто из-за несколько различных сигнатур методов? Каковы последствия игнорирования предупреждения?

+0

Эдди указал на обман. Я голосовал, чтобы закрыть свой собственный вопрос, но я подумал, что хозяин может закрыть его. – Dana

+0

Дана, проверьте [Проблема компиляции примера K & R] (http://stackoverflow.com/questions/616906/problem-compiling-kr-example/616929), и вы, вероятно, найдете ответ на свой вопрос. Сообщите нам, если вы этого не сделаете. – Eddie

ответ

1

Один из способов попытаться диагностировать это, чтобы увидеть, что произойдет, если вы замените выражение на?: Только одним из двух.

Если это происходит только для strcmp, а не numcmp, то это вполне может быть из-за const char *. Я думаю, что хотя char * всегда можно преобразовать в void *, вы не можете преобразовать const char * в void * как «безопасно».

Если это так, то, возможно, речь идет о какой-то проблеме с указателями функций, где работает char *, преобразованный в void *, но сигнатуры должны быть одинаковыми и иметь пустоты вместо символов.

3

Короткий ответ: K & R не знал C.

Длинный ответ: Они были инвалидами тот факт, что, когда они начали, , никто не знал C, так что они были своего рода выдумываю, как они пошли.

(Немного) менее легкомысленная форма длинного ответа: Язык эволюционировал (некоторые сказали бы изменил) совсем немного, так как K & R был написано, но если вы не получили версию электронной книги с помощью динамического примера морфинг, примеры в вашей копии K & R не будут соответствовать языку «новый и одобренный» («теперь с еще большим количеством ANSI!»).

7

Хотя вы можете неявно отбрасывать char * в void *, вы не можете сделать то же самое для указателя функции с этими типами (без предупреждения). Компилятор более осторожен при сопоставлении типов с сигнатурами функций.

Не говоря уже о том, что то, что происходит внутри qsort, будет противоположным: то есть, void * будет передан char * в numcmp и const char * в strcmp.

И в этом случае компилятор должен выдать предупреждение. Если вам действительно нужно использовать функцию, которая не имеет те же типы, что и параметры, возможно, вы должны использовать функцию-оболочку, которая соответствует типам, а затем делает соответствующее явное приведение при вызове исходной функции.

Например:

static int strcmp_wrapper(void* s1, void* s2) { 
    return strcmp((char*)s1, (char*)s2); 
} 

static int numcmp_wrapper(void* n1, void* n2) { 
    return numcmp((char*)n1, (char*)n2); 
} 

qsort((void **) lineptr, 0, nlines-1, 
     (numeric ? numcmp_wrapper : strcmp_wrapper)); 

и современной подписи для QSort является

void 
qsort(void *base, size_t nel, size_t width, 
     int (*compar)(const void *, const void *)); 

Вопрос const, кажется, не вступают в игру в вашем вопросе, но K & R не есть const.

+0

Другой вариант - изменить тернарное выражение на следующее: числовое? (int (*) (void *, void *)) numcmp: (int (*) (void *, void *)) strcmp); Просто просто передайте две различные функции отдельно для qsort. Это также позволит избежать любых предупреждений, данных компилятором – bryanph