//File a.c
void main()
{
test();
}
//File b.c
#include<stdio.h>
void test()
{
printf("Hi, I am test.");
}
我使用“gcc a.c b.c”编译此代码。然后我运行'a.out',输出结果是“你好,我正在测试”。我的问题是在a.c文件中没有test()的声明,为什么代码要编译?在没有声明的情况下在另一个文件中调用函数不会导致编译错误
//File a.c
void main()
{
test();
}
//File b.c
#include<stdio.h>
void test()
{
printf("Hi, I am test.");
}
我使用“gcc a.c b.c”编译此代码。然后我运行'a.out',输出结果是“你好,我正在测试”。我的问题是在a.c文件中没有test()的声明,为什么代码要编译?在没有声明的情况下在另一个文件中调用函数不会导致编译错误
C语言中的函数是extern
默认情况下,这意味着连接将能够给一个函数从文件a
连接到文件b
即使没有程序员编写#include
或extern
。
我的海湾合作委员会编译它与这个警告:warning: implicit declaration of function...
的含义,通过看test();
编译器猜测什么test
是,并继续。如果您已经定义test
为static
会失败,因为static
柜台默认extern
一两件事,我想你应该注意的是这implicit declaration
也使得编译器猜测的test
返回类型,并且它会认为类型是int
。这可能会导致问题。
代码编译,因为这是C标准所要求的(至少在1999年之前)。支持在1999年标准中被删除,尽管一些编译器仍然支持它 - 尽管它们可以被配置为在这种情况下发出警告(例如关于隐式声明)。
具体而言,出于C89/90向预标准C的向后兼容性的考虑,代码调用函数的尝试隐式声明该函数返回int
并接受可变参数列表。
这是当编译器正在通过交流转换器
链接时会发生什么,它会工作,因为函数具有相同的名称。
如果调用函数的方式(返回值的用法和参数类型的数量)与函数的定义方式相匹配,这在实践中可行。如果没有匹配,结果可能是未定义的行为。例如,如果函数是用4个参数定义的并且使用全部4个,但调用者提供了3个,则行为是未定义的。同样,如果函数被定义为返回double
,但调用者认为它返回int
。
实际上,最好在所有编译单元被调用之前声明所有函数(例如,通过包含一个头文件)。这使得编译器有机会检查函数被调用的方式是否与其声明匹配。
还要注意的是,在所有C标准中,main()
返回int
,而不是void
。支持main()
返回void
是一个编译器扩展。
这些连接? –
您是否看到警告?当我在你的代码中使用'gcc'时,我看到“隐式声明'test'”的警告。 – lurker
购买C教程书。那么你会明白为什么。切勿关闭警告 –