POD类型的零初始化

时间:2014-09-12 08:44:52

标签: c++ initialization

struct Foo
{
    char name[10];
    int  i;
    double d;
};

我知道我可以用以下内容对所有POD类型的所有成员进行零初始化:

Foo foo = {0};

我可以进一步简化为:

Foo foo = {};

与原生数组一样? (int arr[10] = {};


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

我在这个主题上发现的大部分教程建议使用{0},没有使用{},例如this guide,并且它被解释为这是有效的,因为聚合初始化规则是递归; ,这比解释更容易引起混淆。

1 个答案:

答案 0 :(得分:4)

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

  

如果列表中的 initializer-clauses 少于   聚合中的成员,然后每个成员未明确初始化   应从其大括号或等于初始化程序或if,如果   来自空的初始化程序没有大括号或等于初始化程序   清单(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类必须有一个简单的(因此不是用户提供的)默认构造函数,因此它们的值初始化意味着零初始化。