扭曲逻辑:一个文件中的全局变量指的是extern变量,但也由该extern变量引用 [英] twisted logic: a global variable in one file refers to an extern variable but is also refered by that extern variable

查看:229
本文介绍了扭曲逻辑:一个文件中的全局变量指的是extern变量,但也由该extern变量引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

fileA.cpp:

fileA.cpp:

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

fileB.cpp

fileB.cpp

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

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

Compiled and linked and ran, out come in the debug and release mode is 0,0 My question is how it works, why there is no issue in linking stage? I'm using VC++2003.

推荐答案

初始化器覆盖 extern 关键字,所以没有什么神奇关于这一点:你只是声明和定义两个完全不相关的变量在不同的函数。

The initialiser overrides the extern keyword, so there's nothing "magical" about this: you're just declaring and defining two completely unrelated variables in different functions.


[C ++ 14:3.1 / 2]: 声明是定义没有指定函数体(8.4)的函数包含 extern 说明符(7.1.1)或 linkage-specification 25 (7.5)且既不是初始化程序也不是函数体,它在类定义中声明一个静态数据成员,9.4),它是类名声明(9.1),它是一个 opaque-enum-declaration (7.2),它是一个 template-parameter (14.1)它是不是 function-definition 的声明符的函数声明符中的参数声明(8.3.5),或者是 typedef 声明(7.1.3),
an 别名声明(7.1.3),使用声明 3),一个 static_assert声明(第7条),一个属性声明(第7条),一个空声明或 using-directive (7.3.4)。

[C++14: 3.1/2]: 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
$ b

fileB.cpp

extern int iB;
int iA = 2*iB;

现在,两个对象都必须在发生其他事情之前进行静态初始化(按位全零)。当动态初始化稍后发生时,取决于fileA.cpp或fileB.cpp中的静态存储持续时间对象是否首先被初始化(并且你不知道将是什么顺序) 初始化为零 iA (然后 iA 按预期初始化为 2 * iB iA 初始化为零 iB 乘以2,仍然是2(然后 iB 初始化为零 iA )。

Now, both objects necessarily undergo static initialization (to bitwise all-zeroes) before anything else happens. When dynamic-initialization later takes place, depending on whether the static-storage-duration objects in fileA.cpp or fileB.cpp get initialised first (and you can't know what order that'll be) either iB is initialized to a zero iA (then iA is initialized to 2*iB as expected), or iA is initialised to a zero iB multiplied by two, which is still two (then iB is initialized to a zero iA).

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

Either way, both objects are going to end up, via well-defined semantics, having a value of zero.

这篇关于扭曲逻辑:一个文件中的全局变量指的是extern变量,但也由该extern变量引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆