POD类型的零初始化

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

我知道可以使用以下方式将这种POD类型的所有成员初始化为0:

Foo foo = {0};

我可以进一步简化这个问题吗?
Foo foo = {};

想使用类似于原生数组的方式吗? (int arr[10] = {};)


我不是在问当使用{0}进行初始化时,除了第一个成员外,其他成员是否也会被初始化为零。 我知道这个问题的答案是肯定的。我想知道的是第一个0是否可以在语法上省略。

我找到的大多数关于这个主题的教程都建议使用{0},没有人使用{},例如这个指南,并且解释为这是因为聚合初始化规则是递归的;,这给人们带来了更多的困惑而不是说明。


@JoachimPileborg:这是非常误导人的。int n;就像是默认构造,但不会设置为零。相反,{}就像是对数据进行值初始化。 - Kerrek SB
1个回答

5
如所述,这是聚合初始化。适用规则为(§8.5.1 [dcl.init.aggr]/p7):
如果在列表中比聚合中的成员少,则每个未显式初始化的成员都应从其brace-or-equal-initializer或,如果没有brace-or-equal-initializer,则从空初始化程序列表 (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类必须具有平凡的(因此不是用户提供的)默认构造函数,因此对它们进行值初始化也意味着零初始化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接