30

While I was reading C++ reference, I had a question about this paragraph:

Note: out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C++.

Is there any technical reason that prevents C++ from supporting out-of-order designated initialization?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Sadeq
  • 7,795
  • 4
  • 34
  • 45

2 Answers2

28

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.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 2
    I also did a [twitter poll on this recently](https://twitter.com/shafikyaghmour/status/1007671525313413122) – Shafik Yaghmour Nov 11 '18 at 16:06
  • 8
    I do not see a problem if it would be specified as: order of initialization will be the same as members order. It happened with init list already before. Are there any negative consequences if this is allowed? – Germán Diago Jan 30 '19 at 05:28
  • 1
    @GermánDiago, I guess they consider it (allowing arbitrary order in member init list) a bad design decision, and don't want to spread it further: after all, hopefully most programmers never violate that order anyway, thanks to `-Wall`. – GreenScape Sep 10 '19 at 12:24
  • They should just allow most/all + require warnings. Esp. in the shadow of much bigger problems that have been embraced (like the impossibly cumbersome init. rules, incl. legitimizing uninitialized data _in some cases, but not others_, and even euphemizing it as "default-initialized" -- hilarious...:) ) – Sz. Mar 02 '23 at 11:11
7

Having only a small fraction of designated initialization options from C is painful. Perhaps it will be rectified in the future. For now, some compilers are a bit less strict than C++20 standard. This snippet:

struct A {int x, y;};
A a = {.y=2, .x=4};

compiles with a warning and runs fine with clang-10.0.0 and newer (see https://godbolt.org/z/Ybnzz5chx).

Paul Jurczak
  • 7,008
  • 3
  • 47
  • 72