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。
答案 0 :(得分:3)
初始化器会覆盖extern
关键字,所以没有什么“神奇”的:你只是在不同的函数中声明和定义两个完全不相关的变量。
[C++14: 3.1/2]:
声明是定义,除非声明函数而未指定函数体(8.4),它包含{{1 }说明符(7.1.1)或连接规范 25 (7.5)既不是初始化程序也不是 function-body ,它在类定义(9.2,9.4)中声明一个静态数据成员,它是一个类名声明(9.1),它是一个 opaque-enum-declaration (7.2),它是 template-parameter (14.1),它是函数声明符中的参数声明(8.3.5),它不是a的声明符。 function-definition ,或者是extern
声明(7.1.3), alias-declaration (7.1.3), using-declaration (7.3.3), static_assert-declaration (第7条), 属性声明(第7条),空声明(第7条)或使用指令(7.3.4)。
您的计划因此等同于以下内容:
fileA.cpp
typedef
fileB.cpp
#include <iostream>
extern int iA;
int iB= iA;
int main()
{
std::cout<<iA<<','<<iB;
}
现在,在发生任何其他事件之前,两个对象都必须进行静态初始化(以按位全零)。稍后进行动态初始化时,取决于fileA.cpp或fileB.cpp中的static-storage-duration对象是否首先被初始化(并且无法知道将是什么顺序) extern int iB;
int iA = 2*iB;
初始化为零iB
(然后iA
按预期初始化为iA
),或2*iB
初始化为零iA
}乘以2,仍为2(然后iB
初始化为零iB
)。
无论哪种方式,两个对象都将通过明确定义的语义结束,其值为零。