The safety and readability are nice; but WHY do they have to be in order? That is so typically clueless. Such an obvious feature, screwed up in a way that only a C++ committee member could.
Initializers for members are _always_ run in the order the member is declared - this applies even in constructor initializing lists, see https://en.cppreference.com/w/cpp/language/constructor#:~:te... - it doesn't matter what order you declare the initializers in, and clang will warn you if you write your initializers in an order other than what they will be executed in. Designated initializers are the same way, it's probably best that the behavior is consistent across methods of constructing.
Why is it this way? As best as I can find it's so that destructors always run in reverse order of construction, I guess there could be some edge cases there that matter. It's not the strongest argument, but it's not nothing.
> Why is it this way? As best as I can find it's so that destructors always run in reverse order of construction, I guess there could be some edge cases there that matter. It's not the strongest argument, but it's not nothing.
I have seen my share of teardown races that were fixed by reordering data members. There's nothing quite like having a mutex torn down before the object that it's guarding.
Running destructors in reverse order of construction is really the only thing that makes sense in an RAII world. It's the same argument as running the destructors in reverse order of construction when exiting a scope.
That's still not a great reason for designated initializers being restricted in the same way they were in C90, especially given the advantage of hindsight. It makes a ton of sense if you have explicit dependencies between data members created during construction, but I can't see a way that you can create those dependencies with designated initializers.
Why does construction and destruction order need to be deterministic?
Well, consider what would happen if you had members whose value depends on other members. For example, one member is a pointer to another. Or perhaps one member uses RAII to hold a lock and another controls a resource.
Deterministic construction and destruction order is a fundamental feature of C++. Calling it clueless is just an indication one does not know C++.
> Why does construction and destruction order need to be deterministic?
That question presupposes a particular compiler implementation of designated initializers. Indeed, C90 had the fixed-order requirement until C99 decided this was unnecessary and removed it.
> Well, consider what would happen if you had members whose value depends on other members.
Can you specify a designated initializer in that way, though? Either you specify a value, or you don't; I'm not aware of a way to introduce dependencies between members with a designated initializer. Yes, you can add a default initializer to a specific member, but that only kicks in if it's unspecified by the designated initializer.
With a constructor initializer list, sure, you can absolutely introduce dependencies on previously-constructed members. But that's not the case with a designated initializer.