Why C++20 doesn’t support out-of-order designated initializer?

Yes, the rationale is covered in Annex C (informative)
Compatibility
specifically [diff.dcl]p10 (emphasis mine):

Affected subclause: [dcl.init.aggr] Change: In C++, designated
initialization support is restricted compared to the corresponding
functionality in C. In C++, designators for non-static data members
must be specified in declaration order, designators for array elements
and nested designators are not supported, and designated and
non-designated initializers cannot be mixed in the same initializer
list. Example:

struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2};  // valid C, invalid C++
int arr[3] = {[1] = 5};         // valid C, invalid C++
struct B b = {.a.x = 0};        // valid C, invalid C++
struct A c = {.x = 1, 2};       // valid C, invalid C++

Rationale: In C++, members are destroyed in reverse construction order and the elements of an initializer list are evaluated in lexical order, so field initializers must be specified in order.
Array designators conflict with lambda-expression syntax.
Nested designators are seldom used.

The first revision of the proposal also discusses this topic:

To meet these expectations for guaranteed copy elision, we require the designators to appear
as a subsequence of the data member declaration sequence, so that the evaluation order
matches the declaration order, and it is also textually left­to­right in designated initialization

You can obtain the last revision here.

Leave a Comment