静态constexpr变量的自我初始化是否格式良好?

时间:2015-12-14 20:52:42

标签: c++ language-lawyer c++14 constexpr c++17

在全局命名空间中给出以下声明:

constexpr int x = x;

结构良好吗?

草案C ++ 14标准部分3.6.2 [basic.start.init] 说:

  

具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5)   在进行任何其他初始化之前。 [...]

似乎使得示例定义良好的是x在常量初始化期间使用自己的值进行初始化,由于初始化为零,因此将0

这是真的吗?铿锵accepts this codegcc produces a diagnostic

error: the value of 'x' is not usable in a constant expression
constexpr int x = x;
                  ^

1 个答案:

答案 0 :(得分:23)

这被defect report 2026: Zero-initialization and constexpr澄清并变得格格不入,问:

  

根据3.6.2 [basic.start.init]第2段,

     
    

具有静态存储持续时间的变量(3.7.1 [basic.stc.static])或     线程存储持续时间(3.7.2 [basic.stc.thread])应为     在任何其他初始化之前零初始化(8.5 [dcl.init])     发生了。

  
     

这是否也适用于常量初始化?例如,   如果以下形式良好,依靠假定的   在常量初始化之前进行零初始化?

constexpr int i = i;
struct s {
  constexpr s() : v(v) { }
  int v;
};
constexpr s s1;

拟议决议案前的说明如下:

  

CWG同意在这些情况下应该将常量初始化视为发生而不是零初始化,从而使声明格式不正确。

并且提议的决议澄清了许多变化,删除了以下措辞:

  

具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5)   在进行任何其他初始化之前。 [...]

并添加以下措辞:

  

如果未执行常量初始化,则具有静态存储持续时间(3.7.1 [basic.stc.static])或线程存储持续时间(3.7.2 [basic.stc.thread])的变量为零初始化(8.5 [dcl.init])。 [...]

这是一个很大的变化,它将 [basic.start.init] 重命名为 [basic.start.static] 并创建了一个新的部分 [basic .start.dynamic] 并修改 [stmt.dcl]