No, an object whose type is your aggregate class C has only two elements: the base class subobject of type B and the member named z. Likewise, the initializer-list which initializes c contains two elements: the first is the initializer-list "{ { .x = 10 }, 20 }" and the second is the literal 30. Since one of those initializers happens to itself be an inner initializer-list and the element is also an aggregate type, the list-initialization process happens recursively to initialize the elements of the B subobject, then to initialize the element of the A subobject. A note in [decl.init.aggr] paragraph (4.2) notes that exactly this sort of semantic recursion can happen.

(Paragraph 15 explains how and when braces around elements of a subaggregate's initializer can sometimes be elided, but this is still all in terms of a direct base class, not an indirect base class, being an aggregate member.)

-- Andrew Schepler


On Fri, Nov 15, 2019 at 8:00 AM Vladimir Grigoriev via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
The following phrase from the C++ Standard (9.3.1 Aggregates, p. #2) confuses

2 The elements of an aggregate are:
(2.2) — for a class, the direct base classes in declaration order, followed by the direct non-static data members (11.3) that are not members of an anonymous union, in declaration order.

Should is there the word "recursively" be inserted  somewhere in the phrase relative to the direct base classes?

This would make for example this initialization more clear

#include <iostream>

struct A
{
int x;
};

struct B : A
{
int y;
};

struct C : B
{
int z;
};

int main()
{
C c = { { { .x = 10 }, 20 }, 30 };

std::cout << "c.x = " << c.x << ", " << "c.y = " << c.y << ", c.z = " << c.z << '\n';
}

 

With best regards,

Vlad from Moscow

You can meet me at http://cpp.forum24.ru/ or www.stackoverflow.com or http://ru.stackoverflow.com
--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion