In this code, will all 100 items of C.B
be initialized to zero?
struct A { int B[100]; int D; };
A C = {0, 0};
It seems to work, but memory could have just been empty in advance.
The line
A C = {0, 0};
Performs value initialization of the aggregate A
. According to the standard, the braces can be omitted for aggregate initialization:
8.5.1 Aggregates[dcl.init.aggr]/12
Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a sub- aggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member.
[Example:
float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };
is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0], y[0][1], and y[0][2]. Likewise the next two lines initialize y[1] and y[2]. The initializer ends early and therefore y[3]'s elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the list are used. Likewise the next three are taken successively for y[1] and y[2]. — end example ]
Next
8.5.1 Aggregates[dcl.init.aggr]/7
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal- initializer, from an empty initializer list.
In your case, this mean that the first 0
is assigned to B[0]
and the second 0
is assigned to B[1]
. According then to 8.5.1/7, the rest of the elements are value-initialized.
However, for clarity in this case, you should use A C = {{0}, 0};
, or, better
A C{}; // or A C = {};
The only thing that worries me a bit is the g++ warning (-Wextra
):
warning: missing initializer for member 'main()::A::D' [-Wmissing-field-initializers] A C {0,0};
But according to my interpretation of the standard above, you should be OK and D
should have been initialized. I even tested it with some placement new
, and the result is as expected
#include <iostream>
int main()
{
struct A { int B[100]; int D;};
A memory{};
memory.D = 42;
std::cout << memory.D << std::endl;
// let's 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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With