默认初始化的含义在C 11中发生了变化



c 2003 8.5/5说:

to default-initialize 类型的对象表示:

- 如果t是非POD类类型(第9条),则调用T的默认构造函数(初始化为 如果t没有可访问的默认构造函数,则不良形式);

- 如果t是数组类型,则每个元素默认initialized;

- 否则,该对象为零initialized

[添加了强调。]

C 2011标准将最后一项更改为

- 否则,未执行初始化

这似乎是某些程序的破坏性变化。这是故意的吗?

编辑

这是一些激励此问题的代码:

class Foo {
  public:
    Foo() : m_values() {}
    int m_values[3];
};

在C 11之前,我认为默认构造函数中对m_values的明确提及 default-initialize 该数组。而且由于数组的元素是标量的,所以我希望意味着这些值都设置为0。

在C 11中,似乎不再保证这种情况会发生。但是,也许正如Mooing Duck在评论中指出的那样,也许这不再是默认初始化的案例,而是保留预期行为的其他一些形式。欢迎引用。

最终效果几乎相同。在C 03中,使用 default-initialize 的使用仅限于非POD类类型,因此最后一点从未应用。在C 11中,该标准通过在使用默认限制的位置消除条件来简化措辞,并更改默认限制化的定义以覆盖所有案例,以与以前发生的事情相对应。

根据cppreference.com(因为它使用比标准更友好的语言):

在三种情况下执行默认初始化:

3)当基类或非静态数据成员未提及 构造函数初始化列表和该构造函数称为

值初始化是在三种情况下进行的:

3,7)当非静态数据成员或基类初始化时 使用成员初始化器与一个空括号or braces (since C++11)

使用

请注意,C 11部分属于or braces,而不是整个段落。

和:

to-initialize t type t type the the type:
- 如果t是数组类型,则每个元素都是值initialized;
- 否则,该对象为零initialized

so在C 11 中默认initialization 不会零启动成员,而是 value-initialization dive。

严格来说, default-initialize 的定义已从C 03变为C 11。但是,还必须考虑到对象是_default-initialize_d更改的情况:

§8.5p9C 03状态:

如果未针对对象指定初始化器,并且该对象的(可能是CV合格的)非POD类类型(或其数组),则该对象应默认为initialial;如果对象是constemififif的类型,则基础类类型应具有用户指定的默认构造函数。否则,如果未针对非静态对象指定初始化器,则该对象及其子对象(如果有)具有不确定的初始值;如果对象或其任何子对象是constemififif的类型,则该程序是不形成的。

§8.5p11c 11状态:

如果未针对对象指定初始化器,则该对象被默认为initialized;如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。

正如@Jameskanze已经指出的那样,当未指定非POD类类型的对象的初始化器时,在C 03中执行 default-initialization 。在C 11中,如果未指定初始化器,则(任意类型)的对象(任意类型的)为 default-Initialized 。由于这种变化,还必须更改default-initialize的定义才能与C 03。

兼容。

您的示例与默认initialization 无关。总是这样的情况,其初始化器为空括号的对象是 value-initialized

相关内容

最新更新