非本地静态变量作为类的成员

时间:2017-12-09 15:10:22

标签: c++

关于settings = Settings() 变量有几个问题,但我还没有找到我的问题的答案。我刚刚阅读Scott Meyers' explanation关于static变量的初始化及其可能存在的问题,例如静态初始化顺序fiasco 。我想知道的是:类范围内的static变量是否被认为是非本地的?

我见过的大多数来源都说static非局部变量是在全局staticnamespace中定义的,而namespace局部变量是在函数中定义的。但请考虑这两个翻译单位:

static

// MyClass.h: class MyClass { public: static int z; // Is this non local? }; // MyClass.cpp: int MyClass::z = 4; // MyOtherClass.h: class MyOtherClass { public: static int w; }; // MyOtherClass.cpp: int MyOtherClass::w = MyClass::z; // Potential fiasco? 是非本地的吗?换句话说,我们可以假设zz时被初始化了吗?

1 个答案:

答案 0 :(得分:1)

MyClass::zMyOtherClass::w都是非本地的静态变量。

您的示例可能包含问题。

这是因为MyOtherClass::w引用MyClass::z,这可能(从编译MyOtherClass的角度来看)需要动态初始化[basic.start.static / 3]:

  

允许实现执行a的初始化   变量,静态或线程存储持续时间为静态   初始化即使不需要进行这样的初始化也是如此   静态地,只要

     
      
  • 的动态版本   初始化不会更改静态的任何其他对象的值   或初始化之前的线程存储持续时间,

  •   
  • 初始化的静态版本在初始化变量中产生的值与动态初始化产生的值相同,如果所有不需要静态初始化的变量都是动态初始化的。

  •   
     

[注意:因此,如果   对象obj1的初始化是指对象obj2   命名空间范围可能需要动态初始化和   稍后在同一翻译单元中定义,是否未指定   使用的obj2的值将是完全初始化的obj2的值   (因为obj2是静态初始化的)或者是obj2的值   只是零初始化。例如,

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;     // unspecified:
                    // may be statically initialized to 0.0 or
                    // dynamically initialized to 0.0 if d1 is
                    // dynamically initialized, or 1.0 otherwise 
double d1 = fd();   // may be initialized statically or dynamically to 1.0
  

- 结束说明]

因此,当编译器编译MyOtherClass.cpp时,它不知道MyClass::z将以哪种方式实际初始化,因此它属于"不需要静态初始化"类别。然后它没有说明,MyOtherClass::w将具有什么价值。它可能有

  • 0,当编译器选择静态初始化时

  • 4,如果编译器选择动态初始化它

感谢StoryTeller提请注意这一点。