POD 类型的零初始化

Yu *_*Hao 4 c++ initialization

struct Foo
{
    char name[10];
    int  i;
    double d;
};
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用以下方法对此类 POD 类型的所有成员进行零初始化:

Foo foo = {0};
Run Code Online (Sandbox Code Playgroud)

我可以进一步简化为:

Foo foo = {};
Run Code Online (Sandbox Code Playgroud)

喜欢原生数组?( int arr[10] = {};)


我不是在用 初始化时询问{0},除了第一个成员之外的成员是否都初始化为零。我知道这个问题的答案是肯定的。我在问是否0可以在语法上省略第一个。

我在这个主题上找到的大多数教程都建议使用{0},不使用{},例如,本指南,并且将其解释为This works 因为聚合初始化规则是递归的;,这比解释更令人困惑。

T.C*_*.C. 5

正如所写,这是聚合初始化。适用的规则是 (§8.5.1 [dcl.init.aggr]/p7):

如果列表中的初始化子句少于聚合中的成员数,则每个未显式初始化的成员都应从其花括号或等式初始化器进行初始化,或者,如果没有花括号或等式初始化器,从一个空的初始化列表(8.5.4)。

§8.5.4 [dcl.init.list]/p3 的相关部分是:

对象或类型引用的列表初始化T定义如下:

  • 如果T是聚合,则执行聚合初始化(8.5.1)。
  • 否则,如果初始化列表没有元素并且T是具有默认构造函数的类类型,则对象是值初始化的。
  • 【省略无关项目】
  • 否则,如果初始化列表没有元素,则对象是值初始化的。

简而言之,子聚合是从一个空的初始化列表递归聚合初始化的。其他一切都是值初始化的。所以最终的结果是一切都被值初始化,一切都是一个 POD,值初始化意味着零初始化。


如果T是 POD 但不是聚合,则聚合初始化不适用,因此您在 §8.5.4 [dcl.init.list]/p3 中找到第二个要点,这会导致整个对象的值初始化。POD 类必须有一个简单的(因此不是用户提供的)默认构造函数,因此它们的值初始化也意味着零初始化。