Consider:
struct Person
{
int height;
int weight;
int age;
};
int main()
{
Person p { .age = 18 };
}
The code above is legal in C99, but not legal in C++11.
What was the c++11 standard committee's rationale for excluding support for such a handy feature?
On July 15 '17 P0329R4 was accepted into the c++20 standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
This brings limited support for c99's Designated Initializers. This limitation is described as follows by C.1.7[diff.decl].4, given:
struct A { int x, y; };
struct B { struct A a; };
The following Designated Initializations, which are valid in C, are restricted in C++:
struct A a = { .y = 1, .x = 2 }
is invalid in C++ because designators must appear in the declaration order of the data membersint arr[3] = { [1] = 5 }
is invalid in C++ because array designated initialization is not supportedstruct B b = {.a.x = 0}
is invalid in C++ because designators cannot be nestedstruct A c = {.x = 1, 2}
is invalid in C++ because either all or none of the data members must be initialized by designatorsFor c++17 and earlier Boost actually has support for Designated Intializers and there have been numerous proposals to add support to the c++ standard, for example: n4172 and Daryle Walker's Proposal to Add Designation to Initializers. The proposals cite implementation of c99's Designated Initializers in Visual C++, gcc, and Clang claiming:
We believe the changes will be relatively straightforward to implement
But the standard committee repeatedly rejects such proposals, stating:
EWG found various problems with the proposed approach, and didn't think it's feasible to try solving the problem, as it has been tried many times and every time it has failed
Ben Voigt's comments have helped me to see the insurmountable problems with this approach; given:
struct X {
int c;
char a;
float b;
};
What order would these functions be called in in c99: struct X foo = {.a = (char)f(), .b = g(), .c = h()}
? Surprisingly, in c99:
The order of evaluation of the subexpressions in any initializer is indeterminately sequenced [1]
(Visual C++, gcc, and Clang seem to have an agreed upon behavior as they will all make the calls in this order:)
h()
f()
g()