例如:
#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()
{
}
Run Code Online (Sandbox Code Playgroud)
答案是否保证是666(我在 gcc8.1.0 中测试过,答案是666)或导致未定义的行为?
更重要的是,在这个例子中,对象a和定义A::k在同一个翻译单元中,如果它们在不同的单元中会发生什么,因为
不同翻译单元中静态变量的初始化是不确定顺序的
从我的角度来看,由于在同一个 TU 中初始化顺序是固定的,因此上面示例的答案应该是无限制的。
如果您要将构造函数设为非内联函数,是的,它将保证是您期望的值。
k将进行常量初始化(由于常量初始值设定项),而a的初始化是动态的。所有静态初始化都发生在静态对象的动态初始化之前。但即使是k 动态初始化的:
[basic.start.dynamic](强调我的)
4具有静态存储持续时间的非局部非内联变量的动态初始化是在 main 的第一个语句之前排序还是延迟,是由实现定义的。如果它被推迟,那么它强烈发生在与要初始化的变量在同一翻译单元中定义的任何非内联函数或非内联变量的任何非初始化之前。它是由实现定义的,其中的线程以及程序中的哪些点发生这种延迟的动态初始化。
非内联构造函数适合这样的函数。这是施瓦茨计数器技术的基础。
但在您的示例中,c'tor 是一个内联函数。因此,这只是由于常量初始化而得到 666。如果初始值设定项不是常量表达式,则将根据同一 TU 中的声明顺序a进行动态初始化。k