在C中使用"隐式声明功能"警告有什么含义?

Sie*_*geX 3 c warnings prototype declaration function

正如问题所述,具有"隐含的功能宣告"警告的含义究竟是什么?我们只是在gcc上加了警告标志,发现了很多这些警告的例子,我很好奇在修复它们之前可能会引起什么类型的问题?

另外,为什么这是警告而不是错误.gcc如何成功链接这个可执行文件?正如您在下面的示例中所看到的,可执行文件按预期运行.

以下面两个文件为例:

在file1.c

#include <stdio.h>

int main(void)
{
   funcA();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

file2.c中

#include <stdio.h>

void funcA(void)
{
   puts("hello world");
}
Run Code Online (Sandbox Code Playgroud)

编译和输出

$ gcc -Wall -Wextra -c file1.c file2.c
file1.c: In function 'main':
file1.c:3: warning: implicit declaration of function 'funcA'

$ gcc -Wall -Wextra file1.o file2.o -o test.exe
$ ./test.exe
hello world
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 7

如果函数有一个与隐式声明匹配的定义(即它返回int且具有固定数量的参数,并且没有原型),并且您总是使用正确的参数数量和类型调用它,那么就没有负面影响(除了坏的,过时的风格).

即,在上面的代码中,就好像该函数被声明为:

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

由于这与函数定义匹配,因此对funcA()from的file1.c调用将调用未定义的行为,这意味着它可能会崩溃.在您的架构上,使用您当前的编译器,它显然不会 - 但架构和编译器会发生变化.

GCC能够链接它,因为当函数类型改变时,表示函数入口点的符号不会改变(再次......在当前架构上,使用当前的编译器 - 尽管这很常见).

正确声明你的功能是一件好事 - 如果没有其他原因,而不是因为它允许你给你的函数原型,这意味着如果你用错误的数量或类型的参数调用它的编译器必须诊断它.

  • 稍微澄清一下.如果有疑问(即未定义),编译器会假定函数的返回类型为**int**这是几个C编译器的默认行为.因此假设int funcA(); (3认同)
  • SiegeX:这完全取决于您的架构ABI,以及如何处理函数返回值.在x86上,指针和int返回值都在`%eax`寄存器中传递,因此它是等效的.请注意,在x86_64上,因为`char*`和`int`具有不同的大小,它将截断指针值. (2认同)