Почему назначенные инициализаторы инициализируют элементы данных нулями?

Ниже приведен пример cppref для назначенных инициализаторов :

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

По умолчанию все фундаментальные типы инициализируются по умолчанию, а не нулями в C++.

Почему назначенные инициализаторы инициализируют элементы данных нулями?

2 ответа

b.yбудет инициализирован из пустого списка инициализаторов, как результат, инициализированный нулем до 0.

Для агрегата без объединения элементы, для которых не указан назначенный инициализатор, инициализируются так же, как описано выше, когда количество предложений инициализатора меньше, чем количество членов (инициализаторы элементов по умолчанию, если они предоставлены, в противном случае инициализация пустого списка) :

       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) В противном случае программа некорректна.

Подобъекты без инициализатора (и без инициализатора члена по умолчанию) в инициализации списка (которая является совокупной инициализацией в случае который является агрегатом) инициализируются значением (что является нулевой инициализацией в случае подобъекты). Они не инициализированы по умолчанию.

Это имело место до назначенных инициализаторов и остается таковым, когда вы используете назначенные инициализаторы. Пример:

      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
Другие вопросы по тегам