是(本地)静态初始化允许过早发生?

时间:2015-02-11 11:26:41

标签: c++

假设foo在程序中被调用一次,

void foo()
{
    if(sometimes_false())
    {
        static int xx = func_with_sideeffect();
    }
}

条件不满足,是副作用 1.允许发生 2.强制要求发生(如果我的编译器符合要求,我猜不会) 3.强制要求没有发生

2 个答案:

答案 0 :(得分:3)

具有本地范围和静态存储持续时间的所有变量的非常量初始化从遇到它直到程序结束。因此,如果由于条件而未遇到变量,则不会对其进行初始化,也不会发生副作用。

标准的以下引用支持答案(特别是粗体部分)

6.7声明声明[stmt.dcl]

  

使用static的所有块范围变量的零初始化(8.5)   存储持续时间(3.7.1)或线程存储持续时间(3.7.2)是   在任何其他初始化发生之前执行。不变   具有静态存储的ablock-scope实体的初始化(3.6.2)   持续时间(如果适用)在其块首次执行之前执行   输入。允许实现执行早期初始化   具有静态正读存储持续时间的其他块范围变量   在允许实施的相同条件下   具有静态或线程存储持续时间的静态初始化变量   在命名空间范围(3.6.2)。 否则会初始化这样的变量   第一次控制通过其声明;这样的   变量在完成后被认为是初始化的   初始化。如果通过抛出异常退出初始化,   初始化未完成,因此下次将再次尝试   时间控制进入声明。如果控制进入声明   在初始化变量的同时,并发   执行应等待初始化完成.88如果控制   在变量为的时候递归地重新输入声明   在被初始化时,行为是不确定的。

答案 1 :(得分:1)

答案是3,但你需要考虑线程化。

static int xx将由遇到该变量的第一个线程初始化,C ++ 11将阻止该点的所有其他线程,直到func_with_sideeffect()返回结果已被分配到xx。 (旧版标准不是这样的情况:需要使用互斥锁。)

如果它是具有非平凡析构函数的对象的实例,则预测xx的破坏会更加困难。