C ++ default-initialization是否保留先前的零初始化? [英] Does C++ default-initialization preserve prior zero-initialization?

查看:215
本文介绍了C ++ default-initialization是否保留先前的零初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果具有静态存储持续时间的对象的C ++构造函数不初始化成员,那么是否需要保留先前的零初始化,还是使成员具有不确定的值?

If a C++ constructor for an object with static-storage duration does not initialize a member, is that required to preserve the prior zero-initialization, or does it leave the member with an indeterminate value?

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

My reading of the C++ spec is that it contradicts itself.

例如:

#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 Foo() constructor does not explicitly initialize the member object.x, so according to the note in 12.6.2 paragraph 8:


成员具有不确定的值。

the member has indeterminate value.

但是,通过各种初始化的细节,这似乎
是不正确的。成员object.x是零初始化的,因为它有static-storage-duration,然后我看不到任何改变的东西。

But working through the details of the various initializations, this appears to be incorrect. The member object.x is zero-initialized as it has static-storage-duration, and then I can't see anything that changes that.

关于构造函数, 12.6.2中应用的文本是:

Regarding the constructor, the text in 12.6.2 that applies is:


实体是默认初始化的。

the entity is default-initialized.

在8.5段落7中,默认初始化的相关情况是:

In 8.5 paragraph 7, the relevant case of default initialization is:


... no执行初始化

... no initialization is performed

这意味着前面的零初始化不会被默认初始化所改变。

which I read to mean that the previous zero-initialization is not changed by the default-initialization.

我缺少一些其他文本,在构造函数调用开始时将所有成员重置为不确定值?

Am I missing some other text which resets all members to "indeterminate value" at the start of the constructor call?

I发现关于零初始化和
默认初始化的stackoverflow的各种其他问题,但我看不到任何
分析当默认初始化跟随
时发生的一些同一实体的早期初始化。

I found various other questions on stackoverflow regarding zero-initialization and default-initialization, but I couldn't see any that analyzed what happens when default-initialization follows some early initialization of the same entity.

在这种情况下,可能没有实际效果。但是在一个更复杂的构造函数中,一些成员初始化而另一些没有,编译器是否必须精确地跟踪哪些字节/位被初始化?,或者它只是初始化整个对象(例如,将构造函数简化为memset )?

In this case there is probably no practical effect. But in a more complex constructor, with some members initialized and others not, does the compiler have to track exactly which bytes/bits are initialized?, or can it just initialize the whole object (e.g., simplifying the constructor to a memset() call)?

推荐答案

缺陷报告1787 会导致 N3914 应用于C ++ 14的草稿标准。哪个更改[dcl.init]段落12来自:

Defect report 1787 lead to the change documented in N3914 being applied to the draft standard for C++14. Which change [dcl.init] paragraph 12 from:


如果没有为对象指定初始化程序,则对象为
default - 初始化;如果未执行初始化,则具有
自动或动态存储持续时间的对象具有不确定的值。 [注意:
具有静态或线程存储持续时间的对象为零初始化,
请参见3.6.2。 - end note]

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 ]

到:


如果没有为一个对象指定初始化器,则该对象是
默认初始化的。 当获得具有自动或
动态存储持续时间的对象的存储时,对象具有不确定的
值,如果未对对象执行初始化,则
对象保留不确定值,直到替换该值

(5.17 [expr.ass])。 [注意:具有静态或线程存储
持续时间的对象是零初始化的,请参见3.6.2 [basic.start.init]。 -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被接受之前,但它可以应用进一步回来。

This make it clear the indeterminate value situation only occurs for objects of automatic or dynamic storage duration. Since this was applied via a defect report it probably also applies to C++11 since the defect report occured before C++14 was accepted but it could apply further back as well. The rules for how far back a defect are supposed to apply were never clear to me.

由于放置new是在注释中提出的,同样的修改也修改了部分<

Since placement new was brought up in the comments, the same change also modified section [expr.new], making the indeterminate value portion a comment:


如果省略了new-initializer,对象是默认初始化的
(8.5 [dcl.init]);如果。 [注意:如果不执行初始化,
对象具有不确定的值。 -end note]

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]

该部分的开头是:


[...]由new-expression创建的实体具有动态存储
duration(3.7.4)。[...]

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

这似乎足以应用 [dcl.init] 一节中的更改。

Which seem sufficient to apply the changes in section [dcl.init].

也很有趣,因为在此更改之前,术语 C ++标准中未定义值未定义

This change was also interesting since prior to this change the term indeterminate value was not defined in the C++ standard.

这篇关于C ++ default-initialization是否保留先前的零初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆