扭曲的逻辑:一个文件中的全局变量引用一个外部变量,但也被该外部变量引用

twisted logic: a global variable in one file refers to an extern variable but is also referred by that extern variable

fileA.cpp:

#include <iostream>
extern int iA;
extern int iB= iA;
int main()
{
std::cout<<iA<<','<<iB;
}

fileB.cpp

extern int iB;
extern int iA = 2*iB;

编译链接和运行,调试和发布模式是0,0 我的问题是它是如何工作的,为什么在链接阶段没有问题? 我正在使用 VC++2003.

初始化程序覆盖了 extern 关键字,因此这没有什么“神奇”:您只是在不同的翻译单元中声明和定义两个完全不相关的变量。

来自 Standard for Programming Language C++ - Chapter 3.1:

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).

因此您的程序等同于以下内容:

fileA.cpp

#include <iostream>
extern int iA;
int iB= iA;
int main()
{
std::cout<<iA<<','<<iB;
}

fileB.cpp

extern int iB;
int iA = 2*iB;

在发生任何其他事情之前,这两个对象都必须经过静态初始化(按位全零)。稍后进行动态初始化时,取决于 fileA.cpp 或 fileB.cpp 中的 static-storage-duration 对象是否首先被初始化(而你 不知道 那将是什么顺序) iB 被初始化为零 iA (然后 iA 按预期被初始化为 2*iB ),或者 iA 被初始化到零 iB 乘以二,它仍然是零(然后 iB 被初始化为零 iA)。

无论哪种方式,通过明​​确定义的语义,两个对象最终都将具有零值。