Подтвердить что ты не робот

Почему прототип и определение функции в C могут различаться?

Мне интересно, почему это скомпилируется:

int test();

int main() { return test((void*)0x1234); }
int test(void* data) { return 0; }

Почему компилятор не выдаст никаких ошибок/предупреждений об этом (я пробовал clang, gcc)? Если я изменю возвращаемое значение, оно не будет компилироваться, но аргументы могут отличаться?!

4b9b3361

Ответ 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);