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

3
以下来自于cppref指定初始化器
struct A { int x; int y; int z; };
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0

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

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


3
这符合其他聚合体的初始化方式:它总是将没有初始值的元素归零,无论是否指定。 - HolyBlackCat
2
自C++11起,A b{};将会对所有成员进行零初始化。在扩展语法时为什么要改变这一点呢? - StoryTeller - Unslander Monica
2个回答

8

b.y 将从空初始化列表进行指定初始化,其效果是被零初始化0

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:

对于非联合聚合体,每个未显式初始化的元素将如下初始化:

  • (5.1) 如果该元素有默认成员初始化器 ([class.mem]),则从该初始化器初始化该元素。

  • (5.2) 否则,如果该元素不是引用,则使用空初始化列表 ([dcl.init.list]) 进行复制初始化。

  • (5.3) 否则,程序为非法。


4

在列表初始化中,如果子对象没有初始值(也没有默认成员初始值),则它们会被值初始化(在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

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