当缺少“extern”时,不会发生预期的“重复符号”

时间:2015-01-27 06:50:52

标签: c

在file1.c中

int i;
foo1()
{
.....
}

在file2.c

int i=10;
foo2()
{
.....
}

然后当我gcc file1.c file2.c。它被取得成功,我认为这是不可能的,因为我相信来自编纂者会有duplicate symbol。 那么有人可以告诉我为什么我的代码是在不使用“extern”的情况下成功构建的吗?在这种情况下,C和C ++之间有什么区别吗?

2 个答案:

答案 0 :(得分:3)

形式上,你是对的:这是一个错误。但是大多数C实现都支持它作为扩展(至少在默认情况下)。 C99实际上在信息性附件J中提到它作为一个共同的扩展

  

J.5.11多个外部定义

     

1可能不止一个   对象标识符的外部定义,有或没有   明确使用关键字 extern ;如果定义不一致,   或初始化多个,行为未定义(6.9.2)

答案 1 :(得分:2)

该程序无效。 GCC扩展允许GCC接受它。

要关闭扩展程序,请使用标记-fno-common

GCC documentation说:

  

-fno-common

     
    

在C代码中,控制未初始化的全局变量的放置。 Unix C编译器传统上允许通过将变量放在公共块中而在不同的编译单元中对这些变量进行多种定义。这是-fcommon指定的行为,是大多数目标上GCC的默认行为。另一方面,ISO C不要求这种行为,并且在某些目标上可能会对变量引用带来速度或代码大小的损失。 -fno-common选项指定编译器应将未初始化的全局变量放在目标文件的数据部分中,而不是将它们生成为公共块。这样做的结果是,如果在两个不同的编译中声明了相同的变量(没有extern),则在链接它们时会出现多重定义错误。在这种情况下,您必须使用-fcommon进行编译。使用-fno-common进行编译对于提供更好性能的目标非常有用,或者如果您希望验证程序是否可以在其他始终以这种方式处理未初始化变量声明的系统上运行。