В этом коде будут ли инициализированы все 100 элементов C.B
?
struct A { int B[100]; int D; };
A C = {0, 0};
Кажется, что это работает, но память могла быть пуста заранее.
В этом коде будут ли инициализированы все 100 элементов C.B
?
struct A { int B[100]; int D; };
A C = {0, 0};
Кажется, что это работает, но память могла быть пуста заранее.
Линия
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
}