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

查看:139
本文介绍了扭曲的逻辑:一个文件中的全局变量指的是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)或链接规范 25 (7.5),并且既不是初始化程序也不是 function-body ,它在类定义中声明一个静态数据成员(9.2,9.4),它是一个类名声明(9.1),它是一个 opaque-enum-declaration (7.2),它是 template-parameter (14.1),它是函数声明器中的 parameter-declaration (8.3.5),不是函数的声明器-definition ,或者它是typedef声明(7.1.3), 别名声明(7.1.3),使用声明(7.3.3), static_assert-声明(条款7), 属性声明(第7条),空声明(第7条)或 using指令(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).

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

Your program is thus equivalent to the following:

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中的静态存储持续时间对象(您不知道这将是什么顺序) iB初始化为零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天全站免登陆