Почему прототип и определение функции в C могут различаться?
Мне интересно, почему это скомпилируется:
int test();
int main() { return test((void*)0x1234); }
int test(void* data) { return 0; }
Почему компилятор не выдаст никаких ошибок/предупреждений об этом (я пробовал clang, gcc)?
Если я изменю возвращаемое значение, оно не будет компилироваться, но аргументы могут отличаться?!
Ответы
Ответ 1
Если вы измените:
int test();
в
int test(void);
вы получите ожидаемую ошибку:
foo.c:4: error: conflicting types for ‘test’
foo.c:1: error: previous declaration of ‘test’ was here
Это потому, что int test();
просто объявляет функцию, которая принимает любые параметры (и поэтому совместима с вашим последующим определением test
), тогда как int test(void);
является фактическим прототипом функции, который объявляет функцию, которая не принимает параметров ( и который несовместим с последующим определением).
Ответ 2
int test();
в объявлении функции, ни один параметр не означает, что функция принимает неопределенное количество аргументов.
Это отличается от
int test(void);
что означает, что функция не принимает аргументов.
Объявление функции без параметра - это старый стиль объявления стиля C; C отмечает этот стиль как устаревший и препятствует его использованию. Короче говоря, не используйте его.
В вашем случае вы должны использовать объявление функции с правильным объявлением параметра:
int test(void *data);