初始化程序会覆盖extern
关键字,所以这没有什么“神奇”的:您只是在不同的翻译单元中声明和定义两个完全不相关的变量。
From 编程语言 C++ 标准 - 第 3.1 章 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4527.pdf:
A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it contains the extern
specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function-body, it declares a static data member in a class definition (9.2, 9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), it is a template-parameter (14.1), it is a parameter-declaration (8.3.5) in a function declarator that is not the declarator of a function-definition, or it is a typedef
declaration (7.1.3), an alias-declaration (7.1.3), a using-declaration (7.3.3), a static_assert-declaration (Clause 7), an attribute-declaration (Clause 7), an empty-declaration (Clause 7), or a using-directive (7.3.4).
因此,您的程序相当于以下内容:
文件A.cpp
#include <iostream>
extern int iA;
int iB= iA;
int main()
{
std::cout<<iA<<','<<iB;
}
文件B.cpp
extern int iB;
int iA = 2*iB;
在发生任何其他事情之前,这两个对象都必须经历静态初始化(按位全零)。当稍后进行动态初始化时,取决于 fileA.cpp 或 fileB.cpp 中的 static-storage-duration 对象是否首先被初始化(并且您不知道那会是什么顺序)iB
被初始化为零iA
(then iA
被初始化为2*iB
如预期),或iA
初始化为零iB
乘以二,仍然为零(然后iB
被初始化为零iA
).
无论哪种方式,通过明确定义的语义,这两个对象最终都将具有零值。