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

时间:2010-04-22 04:58:37

标签: c function prototype warnings declaration

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

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

以下面两个文件为例:

file1.c中

#include <stdio.h>

int main(void)
{
   funcA();
   return 0;
}

file2.c中

#include <stdio.h>

void funcA(void)
{
   puts("hello world");
}

编译&amp;输出

$ 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

2 个答案:

答案 0 :(得分:7)

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

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

int funcA();

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

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

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

答案 1 :(得分:1)

它与在块作用域使用非原型函数声明具有相同的行为,在块范围具有 int 返回类型,因为无法指定返回类型,它默认为 {{ 1}},就像 C 中所有没有指定类型的声明一样,一切都是 int

可以隐式声明函数的原因是因为它们只能在文件范围内定义,但是不清楚未定义的变量是块范围还是文件范围,因此是不允许的,相反选择一个并在文件或块范围内提供隐式暂定定义。实际上,实际隐含的声明是一个块作用域,因此您将在每个被引用的函数中第一次引用该函数时收到警告。