C++ 默认初始化是否保留先前的零初始化?

Does C++ default-initialization preserve prior zero-initialization?

如果具有静态存储持续时间的对象的 C++ 构造函数未初始化成员,是否需要保留先前的零初始化,或者它是否会为成员留下不确定的值?

我对 C++ 规范的解读是它自相矛盾。

示例:

#include <iostream>

struct Foo { Foo(); int x; } object;

Foo::Foo() { }

int main() { std::cout << object.x << std::endl; }

Foo() 构造函数没有显式初始化成员object.x,所以 根据12.6.2第8段的注释:

the member has indeterminate value.

但是通过各种初始化的细节,这似乎 是不正确的。成员 object.x 是零初始化的,因为它具有静态存储持续时间,然后我看不到任何改变它的东西。

关于构造器,12.6.2中适用的文字是:

the entity is default-initialized.

8.5第7段中默认初始化的相关案例为:

... no initialization is performed

我读到的意思是之前的零初始化没有被默认初始化改变。

我是否遗漏了一些在构造函数调用开始时将所有成员重置为 "indeterminate value" 的其他文本?

我在 Whosebug 上发现了关于零初始化和 默认初始化,但我看不到任何 分析了默认初始化之后会发生什么 同一实体的一些早期初始化。

这种情况估计没有实际效果。但是在一个更复杂的构造函数中,一些成员被初始化而其他成员没有被初始化,编译器是否必须准确跟踪哪些 bytes/bits 被初始化?或者它是否可以只初始化整个对象(例如,将构造函数简化为 memset( ) 调用)?

Defect report 1787 lead to the change documented in N3914 being applied to the draft standard for C++14。 [dcl.init] 第 12 段来自:

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ]

至:

If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.17 [expr.ass]). [Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2 [basic.start.init]. —end note] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

[...]

这清楚地表明不确定值的情况只发生在自动或动态存储持续时间的对象上。由于这是通过缺陷报告应用的,因此它可能也适用于 C++11,因为缺陷报告发生在 C++14 被接受之前,但它也可以应用得更早。关于缺陷应该应用多远的规则对我来说从来都不清楚。

由于在评论中提出了 placement new,同样的更改也修改了部分 [expr.new],使不确定值部分成为评论:

If the new-initializer is omitted, the object is default-initialized (8.5 [dcl.init]); if. [Note: If no initialization is performed, the object has an indeterminate value. —end note]

该部分的开头说:

[...]Entities created by a new-expression have dynamic storage duration (3.7.4).[...]

这似乎足以应用 [dcl.init].

部分中的更改

此更改也很有趣,因为在此更改之前,C++ 标准中的术语 indeterminate value was not defined