例如:
#include<iostream>
using namespace std;
class A
{
public:
A(){cout<<k<<endl;}//make some output
static int k;
};
A a;//before `k`'s definition
int A::k=666;
int main()
{
}
是否保证答案是666
(我在gcc8.1.0测试过答案是666
)还是导致未定义的行为?
此外,在这个例子中,对象a
和定义A::k
在同一个翻译单元中,如果它们在不同的单元中会发生什么,因为
Initialization of static variables in different translation units is indeterminately sequenced
在我看来,由于在同一个TU中初始化顺序是固定的,所以上面例子的答案应该是不确定的。
最佳答案
如果您要使构造函数成为非内联函数,是的,它会保证是您期望的值。
k
将受制于 constant initialization (由于常量初始值设定项),而 a
的初始化是动态的。所有静态初始化都发生在静态对象的动态初始化之前。但即使 k
被动态初始化:
[basic.start.dynamic] (emphasis mine)
4 It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized. It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.
并且非内联构造函数有资格使用这样的函数。这是 Schwarz Counter 的基础技术。
但在您的示例中,c'tor 是一个内联函数。所以这只是由于常量初始化,你得到 666。如果初始化器不是常量表达式,a
将根据相同的声明顺序在 k
之前进行动态初始化恩。
关于c++ - 静态数据成员是否在所有类对象之前初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54884570/