Why do designated initializers zero-initialize the data members?

1k views Asked by At

Below is from cppref of Designated initializers:

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

By default, all fundamental types are default-initialized rather than zero-initialized in C++.

Why do designated initializers zero-initialize the data members?

2

There are 2 answers

0
leslie.yao On BEST ANSWER

b.y will be initialized from an empty initializer list, as the effect, zero-initialized to 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

From the standard, [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.

0
eerorika On

Subobjects with no initialiser (and no default member initialiser) in list initialisation (which is aggregate initialiation in case of A which is an aggregate) are value initialised (which is zero initialisation in case of int subobjects). They are not default initialised.

This has been the case before designated initialisers, and it remains the case when you use designated initialisers. Example:

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

Same applies to arrays, although there designated initialisers are unfortunately not available in standard 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