在全局命名空间中给出以下声明:
constexpr int x = x;
结构良好吗?
草案C ++ 14标准部分3.6.2
[basic.start.init] 说:
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5) 在进行任何其他初始化之前。 [...]
似乎使得示例定义良好的是x
在常量初始化期间使用自己的值进行初始化,由于初始化为零,因此将0
。
这是真的吗?铿锵accepts this code而gcc produces a diagnostic:
error: the value of 'x' is not usable in a constant expression
constexpr int x = x;
^
答案 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]