繁体   English   中英

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段中的注释:

该成员具有不确定的价值。

但是仔细研究各种初始化的细节,这似乎是不正确的。 成员object.x具有静态存储持续时间,因此被零初始化,然后我看不到有任何更改。

关于构造函数,适用于12.6.2的文本为:

该实体是默认初始化的。

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

...不执行初始化

我读的意思是默认初始化不会更改以前的零初始化。

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

我在stackoverflow上发现了其他一些有关零初始化和默认初始化的问题,但是我看不到有任何问题可以分析当默认初始化跟随同一个实体的早期初始化后发生的情况。

在这种情况下,可能没有实际效果。 但是在一个更复杂的构造函数中,其中一些成员已初始化而其他成员未初始化,那么编译器是否必须准确跟踪要初始化的字节/位?或者它是否可以初始化整个对象(例如,将构造函数简化为memset()调用) )?

缺陷报告1787导致N3914中记录的更改被应用于C ++ 14标准草案 从[dcl.init]第12段更改为:

如果未为对象指定初始化程序,则该对象为默认初始化;否则,默认为初始化。 如果未执行初始化,则具有自动或动态存储持续时间的对象的值不确定。 [注意:具有静态或线程存储持续时间的对象将初始化为零,请参见3.6.2。 —尾注]

至:

如果未为对象指定初始化程序,则该对象将被默认初始化。 当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定的值,并且如果未对该对象执行任何初始化,则该对象将保留不确定的值,直到替换该值为止 (5.17 [expr.ass]) 。 [注意:具有静态或线程存储持续时间的对象被零初始化,请参见3.6.2 [basic.start.init]。 — [end note]如果评估产生不确定的值,则该行为是不确定的,但以下情况除外:

[...]

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

由于注释中出现了new位置,因此相同的更改也修改了[expr.new]部分,使不确定值部分成为注释:

如果省略了new-initializer,则该对象将被默认初始化(8.5 [dcl.init]); 如果。 [注意:如果不执行初始化,则该对象的值不确定。 —尾注]

本节的开头说:

[...]由新表达式创建的实体具有动态存储持续时间(3.7.4)。[...]

似乎足以应用[dcl.init]部分中的更改。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM