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

时间:2015-06-12 12:43:03

标签: c++ compilation linker external

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。

1 个答案:

答案 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)。

无论哪种方式,两个对象都将通过明确定义的语义结束,其值为零。