2017-07-30 66 views
1
//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()的声明,为什么代码要编译?在没有声明的情况下在另一个文件中调用函数不会导致编译错误

+0

这些连接? –

+1

您是否看到警告?当我在你的代码中使用'gcc'时,我看到“隐式声明'test'”的警告。 – lurker

+0

购买C教程书。那么你会明白为什么。切勿关闭警告 –

回答

2

C语言中的函数是extern默认情况下,这意味着连接将能够给一个函数从文件a连接到文件b即使没有程序员编写#includeextern

我的海湾合作委员会编译它与这个警告:warning: implicit declaration of function...的含义,通过看test();编译器猜测什么test是,并继续。如果您已经定义teststatic会失败,因为static柜台默认extern

一两件事,我想你应该注意的是这implicit declaration也使得编译器猜测test返回类型,并且它会认为类型是int。这可能会导致问题。

1

代码编译,因为这是C标准所要求的(至少在1999年之前)。支持在1999年标准中被删除,尽管一些编译器仍然支持它 - 尽管它们可以被配置为在这种情况下发出警告(例如关于隐式声明)。

具体而言,出于C89/90向预标准C的向后兼容性的考虑,代码调用函数的尝试隐式声明该函数返回int并接受可变参数列表。

这是当编译器正在通过交流转换器

链接时会发生什么,它会工作,因为函数具有相同的名称。

如果调用函数的方式(返回值的用法和参数类型的数量)与函数的定义方式相匹配,这在实践中可行。如果没有匹配,结果可能是未定义的行为。例如,如果函数是用4个参数定义的并且使用全部4个,但调用者提供了3个,则行为是未定义的。同样,如果函数被定义为返回double,但调用者认为它返回int

实际上,最好在所有编译单元被调用之前声明所有函数(例如,通过包含一个头文件)。这使得编译器有机会检查函数被调用的方式是否与其声明匹配。

还要注意的是,在所有C标准中,main()返回int,而不是void。支持main()返回void是一个编译器扩展。

相关问题