魔法静态保证右侧只执行一次吗?

NoS*_*tAl 4 c++ static-initialization c++11

如果我有

atomic<int> cnt=0;

int get_int() noexcept
{
   cnt++;
   return rand();
}
Run Code Online (Sandbox Code Playgroud)

然后:

void func()
{
   static const auto value = get_int();
}
Run Code Online (Sandbox Code Playgroud)

我知道初始化时没有竞争条件value,但我不知道是否 get_int()会被调用一次,或者在我的例子中将cnt是1(而不是2,3,4或5).

假设多个线程进入func()并且get_int只有一个呼叫站点func().

Mar*_* A. 8

C++ 11保证不存在竞争条件N3797 - §6.7/ 4:

允许实现在静态或线程存储持续时间内执行其他块范围变量的早期初始化,条件是允许实现在命名空间范围内静态初始化具有静态或线程存储持续时间的变量(3.6.2).否则,在第一次控制通过其声明时初始化这样的变量; 这样的变量在初始化完成后被认为是初始化的.如果通过抛出异常退出初始化,则初始化未完成,因此下次控制进入声明时将再次尝试初始化.如果控件在初始化变量时同时进入声明,则并发执行应等待初始化完成.92如果控件在初始化变量时以递归方式重新进入声明,则行为未定义.[ 例如:

int foo(int i) {
  static int s = foo(2*i); // recursive call - undefined
  return i+1;
}
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

它不是可重入但是线程安全的.确保不会有将调用代码的其他部分get_int()之前func()反正.