考虑由两个文件组成的C程序,
f1.c:
int x;
f2.c:
int x=2;
我的阅读理解是,在C99标准的第6.9.2段中,这个程序应该被拒绝。在我对6.9.2的解释中,变量x
在f1.c
中被暂时定义,但这个暂定定义会在翻译单元的结尾变成实际定义,并且(在我看来)应该像f1.c
包含定义int x=0;
一样运行。
在我试过的所有编译器(和链接器)中,都没有发生这种情况。我尝试过的所有编译平台都会链接上述两个文件,并且x
的值在两个文件中都为2。
我怀疑这不是偶然发生的,也不仅仅是作为标准要求之外提供的“简单”功能。如果你仔细想一下,这意味着链接器对那些没有初始化器的全局变量有特殊支持,而不是那些明确初始化为零的变量。有人告诉我,链接器的这个特性可能在编译Fortran时是必需的。这将是一个合理的解释。
对此有什么想法?标准的其他解释?文件f1.c
和f2.c
不能在一些平台上链接的名称?
注意:这很重要,因为这个问题发生在静态分析的背景下。如果这两个文件在某些平台上可能拒绝链接,分析器应该报错,但如果每个编译平台都接受它,则没有理由警告。
-fno-common
。即使在f2.c
中只有未初始化的int x;
,你也会得到链接器错误。跨编译单元合并试探性定义是不好的,我认为这会导致错误。现在存在extern关键字来正确处理这些事情。 - Sven