为什么指定初始化器对数据成员进行零初始化?

Why do designated initializers zero-initialize the data members?

下面来自 cppref指定初始化器:

struct A { int x; int y; int z; };
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0

默认情况下,所有基本类型在 C++ 中都是默认初始化的,而不是零初始化的。

为什么指定初始化器对数据成员进行零初始化?

b.y 将是 initialized from an empty initializer list, as the effect, zero-initialized0

For a non-union aggregate, elements for which a designated initializer is not provided are initialized the same as described above for when the number of initializer clauses is less than the number of members (default member initializers where provided, empty list-initialization otherwise):

struct A {
  string str;
  int n = 42;
  int m = -1;
};
A{.m=21}  // Initializes str with {}, which calls the default constructor
          // then initializes n with = 42
          // then initializes m with = 21

根据标准,[dcl.init.aggr]/5

For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:

  • (5.1) If the element has a default member initializer ([class.mem]), the element is initialized from that initializer.

  • (5.2) Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list ([dcl.init.list]).

  • (5.3) Otherwise, the program is ill-formed.

列表初始化中没有初始化器(也没有默认成员初始化器)的子对象(在A是聚合的情况下是聚合初始化)是值初始化 (在 int 子对象的情况下是零初始化)。它们不是默认初始化的。

在指定初始化器之前就是这种情况,使用指定初始化器时也是如此。示例:

struct A { int x; int y; int z; };
A b0;                  // default i.e. no initialisation for x,y,z
A b1 {};               // x, y and z are value initialised
A b2 {1};              //    y and z are value initialised
A b3 {.x = 1, .z = 2}; //    y       is  value initialised

同样适用于数组,尽管不幸的是在标准 C++ 中指定的初始化器不可用:

int arr0[3];          // default i.e. no initialisation
int arr1[3] {};       // all are value initialised
int arr2[3] {42};     // all but first are value initialised