我正在学习K&R的C语言,但在书的第4.4部分中对作用域规则感到困惑。在继续之前,让我先贴出我正在使用的源文件。
#include <stdio.h>
void first(void);
int main(void) {
printf("In main.\n");
first();
second();
return 0;
}
void first(void) {
printf("In first.\n");
}
void second(void) {
printf("In second.\n");
}
现在,除非我比想象中的更蠢,这本书给了我这样的想法:函数原型(与函数定义在同一文件中)存在于作用域的原因。也就是说,它们的存在允许在编译文件的顶部声明该函数,以便源文件的其余部分提前被通知一个“对象”的存在,如果我可以这么说的话。
我的问题是,在我正在使用GCC版本4.7.1的Arch Linux虚拟机上,上面的代码无法编译,并显示以下错误:“second type for conflicting”。然而,当相同的代码运行到我物理机器上时,这台机器运行Ubuntu 12.04,带有GCC版本4.6.3,它可以很好地编译。
我的问题是:这是编译器的特性吗?因为如果不是,我很惊讶它能编译通过,因为没有函数原型,如果我理解正确,主要函数不应该知道second的存在。
-Wall
编译,因为在两种情况下都会得到编译器警告。建议使用-Werror
进行编译(至少对于新代码),因为它将所有警告转换为错误,确保您注意到它们。(C的这种原型推断缺陷在C99中被删除,但是GCC仍然支持它,即使在C99模式下也是如此。) - cdhowieint func()
而不是int func(void)
。后者将不允许使用任意数量的参数调用隐式声明的函数,而实际上编译器允许使用任意数量的参数进行调用。 - Blagovest Buyuklievconflicting types for 'second'
,但是我的 gcc-4.6 只有一个警告。 - Daniel Fischer