为什么C语言中函数的原型和定义可能不同?

20

我想知道为什么这段代码会编译通过:

int test();

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

为什么编译器不会对此发出任何错误/警告(我尝试了clang,gcc)? 如果我更改返回值,它就无法编译 - 但参数可能不同?!


1
可能是C void arguments的重复问题。 - Paul R
2个回答

28

如果您更改:

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); 是一个实际的函数原型,它声明了一个不接受参数的函数(并且与随后的定义不兼容)。


3
简要翻译:将其用 C 术语表达,int test() 不仅仅是原型,而只是一个声明。 - Jens Gustedt
但是这种行为很快将被弃用(或者至少是根据 ISO C11 的规定)。 - AnArrayOfFunctions

15
 int test();

在函数声明中,没有参数意味着该函数接受未指定数量的参数。

这与

 int test(void);

这意味着该函数不需要参数。

没有参数的函数声明是旧版C语言风格的函数声明方式;C标记此风格为过时的,并且不鼓励使用它。简而言之,不要使用它。

在您的情况下,您应该使用正确的参数声明来进行函数声明:

 int test(void *data);

我总是忘记 C 会这样做!即使它是 int test(void);,但跨 TU 没有要求发出诊断。 - Flexo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接