扭曲的逻辑:一个文件中的全局变量引用一个外部变量,但也被该外部变量引用
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
)。
无论哪种方式,通过明确定义的语义,两个对象最终都将具有零值。
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 atypedef
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
)。
无论哪种方式,通过明确定义的语义,两个对象最终都将具有零值。