在全局命名空间中给出以下声明:
constexpr int x = x;
这个结构良好吗?
草案C++ 14标准部分3.6.2
[basic.start.init]说:
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应在任何其他初始化发生之前进行零初始化(8.5).[...]
似乎使得示例定义良好的是x
在常量初始化期间使用其自己的值初始化,这将0
归因于零初始化.
这是真的吗?当gcc生成诊断时,clang 接受此代码:
error: the value of 'x' is not usable in a constant expression constexpr int x = x; ^
Shafik Yaghm.. 23
这被澄清并且由缺陷报告2026:零初始化和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.在里面]).[...]
这是一个很大的变化,它将[basic.start.init]重命名为[basic.start.static]并创建了一个新的部分[basic.start.dynamic]并修改了[stmt.dcl]
这被澄清并且由缺陷报告2026:零初始化和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.在里面]).[...]
这是一个很大的变化,它将[basic.start.init]重命名为[basic.start.static]并创建了一个新的部分[basic.start.dynamic]并修改了[stmt.dcl]