有“一个”的含义是什么;隐式函数声明“;C语言的警告?

有“一个”的含义是什么;隐式函数声明“;C语言的警告?,c,function,prototype,warnings,declaration,C,Function,Prototype,Warnings,Declaration,正如问题所述,“隐式功能声明”警告的确切含义是什么?我们刚刚启动了gcc上的警告标志,并发现了相当多的警告实例,我很好奇在修复它们之前,这可能会导致什么类型的问题 还有,为什么这是一个警告而不是一个错误。gcc是如何成功链接这个可执行文件的?正如您在下面的示例中所看到的,可执行文件的功能与预期的一样 以以下两个文件为例: 文件1.c 如果函数的定义与隐式声明相匹配(即,它返回int,具有固定数量的参数,并且没有原型),并且您总是使用正确数量和类型的参数调用它,那么就没有负面影响(坏的、过时的样式

正如问题所述,“隐式功能声明”警告的确切含义是什么?我们刚刚启动了gcc上的警告标志,并发现了相当多的警告实例,我很好奇在修复它们之前,这可能会导致什么类型的问题

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

以以下两个文件为例:

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

也就是说,在上面的代码中,函数被声明为:

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

GCC能够链接它,因为表示函数入口点的符号在函数类型更改时不会更改(同样,在您当前的体系结构上,使用您当前的编译器,尽管这是很常见的)


正确声明函数是一件好事-如果没有其他原因,它允许您为函数提供原型,这意味着,如果使用错误的参数数或参数类型调用它,编译器必须对其进行诊断。

它的行为与在块范围内使用带有
int
返回类型的非原型函数声明的行为相同,因为无法指定返回类型,它默认为
int
,与C中所有未指定类型的声明一样,所有内容都是
int


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

请稍作说明。当有疑问(即未定义)时,编译器会假定函数的返回类型为int,这是一些C编译器的默认行为。因此,假设int funcA()@咖啡馆:很有趣。让我们假设“funcA”的原型是
char*funcA(void)
这样它就返回了一个指向字符串的指针,我在
strcpy
中使用了返回值。使用隐式声明是否等同于执行strcpy(buff,(int)funcA())?我意识到未定义的行为正是如此,但我仍然很好奇我的实现到底在做什么(Linux+gcc)。@CVS:谢谢你的新词汇,我必须记住这个!SiegeX:这完全取决于您的架构ABI,以及如何处理函数返回值。在x86上,指针和int返回值都在
%eax
寄存器中传递,因此它是等效的。注意,在x86_64上,由于
char*
int
的大小不同,它将截断指针值。CVS:隐式声明的类型实际上是C语言规范的一部分,它不仅仅是某些编译器的默认值。
#include <stdio.h>

void funcA(void)
{
   puts("hello world");
}
$ 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
int funcA();