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

Zaf*_*ffy 20 c

我想知道为什么这会编译:

int test();

int main() { return test((void*)0x1234); }
int test(void* data) { return 0; }
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*l R 28

如果你改变:

int test();
Run Code Online (Sandbox Code Playgroud)

至:

int test(void);
Run Code Online (Sandbox Code Playgroud)

你会得到预期的错误:

foo.c:4: error: conflicting types for ‘test’
foo.c:1: error: previous declaration of ‘test’ was here
Run Code Online (Sandbox Code Playgroud)

这是因为int test();简单地声明了一个接受任何参数的函数(因此与后续的定义兼容test),而int test(void);实际的函数原型声明了一个不带参数的函数(并且与后续定义兼容).

  • +1,用C-ish术语表示,`int test()`根本不是原型而只是一个声明. (3认同)

oua*_*uah 15

 int test();
Run Code Online (Sandbox Code Playgroud)

在函数声明中,没有参数意味着该函数采用未指定数量的参数.

这不同于

 int test(void);
Run Code Online (Sandbox Code Playgroud)

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

没有参数的函数声明是旧的C函数声明; C将这种风格标记为过时并且不鼓励使用它.简而言之,不要使用它.

在您的情况下,您应该使用带有正确参数声明的函数声明:

 int test(void *data);
Run Code Online (Sandbox Code Playgroud)