Будет ли {0, 0} инициализировать массив в структуре?

В этом коде будут ли инициализированы все 100 элементов C.B?

struct A { int B[100]; int D; };
A C = {0, 0};

Кажется, что это работает, но память могла быть пуста заранее.

Ответ 1

Линия

A C = {0, 0}; 

Выполняет инициализацию значений агрегат A, Согласно стандарту, скобки могут быть опущены для агрегатной инициализации:

8.5.1 Агрегаты [dcl.init.aggr]/12

Брекеты можно отбросить в списке инициализаторов следующим образом. Если Список инициализаторов начинается с левой скобки, затем следующая список инициализаторов-разделов, разделенных запятыми, инициализирует члены субагрегат; ошибочно, чтобы было больше initializer-clauses, чем члены. Если, однако, список инициализаторов для подзаголовка не начинается с левой скобки, тогда только достаточно инициализатор-предложения из списка, чтобы инициализировать члены подгруппы; любые оставшиеся условия инициализации слева, чтобы инициализировать следующий член совокупности, из которого текущий субагрегат является членом.

[Пример:

 float y[4][3] = {
   { 1, 3, 5 },
   { 2, 4, 6 },
   { 3, 5, 7 }, }; 

является полностью фиксированной инициализацией: 1, 3 и 5 инициализируют первую строку массива y [0], а именно y [0] [0], y [0] [1] и y [0] [2]. Аналогично, следующие две строки инициализируют y [1] и у [2]. Инициализатор заканчивается раньше, и поэтому y [3] элементы инициализируется, как будто явно инициализируется выражением form float(), то есть инициализируются с помощью 0.0. В следующих Например, скобки в списке инициализаторов исключены; Однако Инициализатор-список имеет тот же эффект, что и полностью привязанный initializer-list из приведенного выше примера,

 float y[4][3] = {
   1, 3, 5, 2, 4, 6, 3, 5, 7 }; 

Инициализатор для y начинается с левой скобки, но для y [0] нет, поэтому три элемента из списка. Аналогично, следующие три последовательно выполняются для y [1] и y [2]. - конец примера]

Далее

8.5.1 Агрегаты [dcl.init.aggr]/7

Если в списке меньше предложений инициализатора, чем членов в совокупности, то каждый член явно не инициализирован должны быть инициализированы из его элементарного или равного инициализатора или, если не является инициализатором скобки или равным, из пустого списка инициализаторов.

В вашем случае это означает, что первый 0 назначен B[0], а второй 0 назначен B[1]. Согласно 8.5.1/7, остальные элементы инициализируются значением.

Однако для ясности в этом случае вы должны использовать A C = {{0}, 0};, или, лучше

A C{}; // or A C = {};

Единственное, что меня немного беспокоит, это предупреждение g++ (-Wextra):

предупреждение: отсутствует инициализатор для элемента main():: A:: D ' [-Инструкции инициализатора поля] A C {0,0};

Но согласно моей интерпретации вышеприведенного стандарта, вы должны быть в порядке, а D должен быть инициализирован. Я даже тестировал его с некоторым размещением new, и результат ожидался

#include <iostream>

int main()
{
    struct A { int B[100]; int D;};
    A memory{};
    memory.D = 42; 
    std::cout << memory.D << std::endl;

    // let place something an A at the location of memory
    A* foo = new (&memory) A{0,0}; 
    // line below outputs 0, so D is erased; not the case if A* foo = new (&memory) A; 
    std::cout << memory.D << std::endl; // outputs 0
}