考虑的两个文件组成的C程序,
在f1.c:
int x;
f2.c:
int x=2;
我的第6.9.2读C99的标准是,这个程序应该被拒绝。 在我的6.9.2解释变量x
的初步定义f1.c
,但这种试探性的概念却在翻译单元结束的实际定义,以及(在我看来),因此应该表现为,如果f1.c
载定义int x=0;
。
与所有的编译器(并且,重要的是,接头)我能试试,这是不会发生什么变化。 所有编译平台我试着做了以上两个文件链接,和值x
是在这两个文件2。
我怀疑这会发生意外,或只是作为一个“易”功能,除了什么标准要求提供。 如果你仔细想想,这意味着在链接器为不具有初始化,而不是那些明确初始化为零的全局变量的特殊支持。 有人告诉我,连接功能可能需要编译的Fortran反正。 这将是一个合理的解释。
这个有什么想法? 该标准的其他解释? 对哪些文件名称平台f1.c
和f2.c
拒绝被联系在一起的?
注:因为在静态分析的环境中出现的问题,这是非常重要的。 如果这两个文件可以拒绝一些平台链接,分析应该抱怨,但如果每个编译平台,接受它,那么就没有任何理由来警告它。
又见什么是用C的extern变量 。 这在信息附件J作为共同延伸C标准中提到:
J.5.11多重外部定义
可能有一个对象的标识符,具有或不具有明确使用关键字的extern的多于一个的外部定义; 如果定义不同意,或一个以上的初始化,行为是不确定的(6.9.2)。
警告
作为@litb这里所指出的,并在我的答案交叉引用的问题明确规定,通过多个定义为一个全局变量会导致不确定的行为,这是说:“任何事情都可能发生”的标准的方式。 其中一个可能发生的事情是,当你所期望的程序的行为; 和J.5.11说,大约“你可能会幸运往往比你应得的。” 但是,这依赖于外部变量的多个定义程序 - 有或没有明确“的extern”关键字 - 不是一个严格符合程序,并且不保证工作无处不在。 等价的:它包含可能会或可能不会显示自己的错误 。
也有一些是被称为“公共扩展”的标准,其中定义变量多次被允许的,只要变量只初始化一次。 见http://c-faq.com/decl/decldef.html
所链接的页面表示,这是恰当的Unix平台 - 我想这是对C99作为C89相同的 - 虽然也许它已经通过更多的编译器,形成某种事实上的标准。 有趣。
这是我的回答澄清由olovb评论:
纳米用于从编译的目标文件的输出为“int X;”。 在这个平台上,符号都加上了“_”,也就是变量x出现_x。
00000000 T _main
U _unknown
00000004 C _x
U dyld_stub_binding_helper
纳米的输出用于从编译的目标文件“INT X = 1;”
00000000 T _main
U _unknown
000000a0 D _x
U dyld_stub_binding_helper
纳米的输出用于从编译的目标文件“INT X = 0;”
00000000 T _main
U _unknown
000000a0 D _x
U dyld_stub_binding_helper
纳米用于从编译的目标文件的输出“外部INT X;”
00000000 T _main
U _unknown
U dyld_stub_binding_helper
编辑:纳米从编译的目标文件的输出“外部INT X;” 其中,x是在的功能的一个实际使用
00000000 T _main
U _unknown
U _x
U dyld_stub_binding_helper