Having this structure:
struct A {
struct B {
int a = 21;
int b;
int c = 22;
int d;
int e = 23;
};
B b1 = { 11, 12 };
B b2 = { 11, 12, 13 };
int x;
};
And declaring:
A a = { { 1, 2, 3, 4 }, { 1 }, 5 };
According to both Clang (3.8.0) and GCC (5.4.0), these are the values of the 8 possible combinations (a.b1.e and a.b2.a are repeated cases), regarding where the initial value is taken from (or not), :
a.b1.a = 1 // 111
a.b1.b = 2 // 110
a.b1.c = 3 // 101
a.b1.d = 4 // 100
a.b2.b = 0 // 010 // Why not 12 instead of 0? -> Explained in N3605
a.b2.c = 22 // 011 // Why not 0 instead of 22 ? Why not 13 ?
a.b2.d = 0 // 000
a.b2.e = 23 // 001 // Why not 0 instead of 23 ?
Taking into account the example in N3605 and the C++14 Standard (ISO/IEC 14882:2014), Section 8.5.1, Paragraph 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 (8.5.4).
I assume case 010 is correct. Then, why cases 011 (a.b2.c) and 001 (a.b2.e) are not also equal to zero? Case 010 is zero because a.b2 "does have an initializer", therefore "the non-static data member initializer is ignored" (N3605 again). Why the default member initializers are not ignored as well?
In fact, reading the C++14 Standard quote it would make more sense to me that case 010 would be 12 (it is zero) and cases 011 and 001 would be zero (as they actually are). So what I don't understand is why a.b2 is sometimes considered to "have an initializer" and other times it is not.
{ 1 }"replaces" the{ 11, 12, 13 }. The inner default initializers still apply unless the init-list overrides them (which happens tob2.a, but notb2.candb2.e). - Baum mit Augen♦