3 ms·
struct S { int A; int B = A; int C; }; int i = 0; S s = {.C = i++, .A = ++i}; What would you expect code like this to do?
by zalyalov 3y ago
struct S {
int A;
int B = A;
int C;
};
int i = 0;
S s = {.C = i++, .A = ++i};
What would you expect code like this to do?
- rwmj 3y agoI wouldn't write that, and if someone did they'd get to keep all the pieces.
- flohofwoe 3y agoThe only useful solution for C++ would be to let the compiler reorder the initialization in declaration order, e.g. first A, then B, then C. This would still be a lot better for 99% of real world use cases than requiring the programmer to manually place the items in declaration order.
- IshKebab 3y agoThis would be a big footgun though. That already happens for initialising class members in constructors and it's enough of a footgun that compilers have a warning to tell you if your initialisation order is different to the declaration order.
- jzwinck 3y agoDoesn't the same footgun apply to function call arguments which are evaluated in an unspecified order? f(a++, b++) That footgun doesn't seem to have very much impact in the real world that I've seen. Largely because people do not write complex expressions like that anymore. Since we already mostly avoid such expressions, we may as well take the benefit for designated initializers.
- IshKebab 3y agoYeah that is a footgun too. Enough that Rust defines argument evaluation order. It is a much smaller footgun though and I don't recall ever being bitten by it. I have definitely been bitten by member initialisation order though multiple times. Generally because of questionable designs where one member is passed as a parameter of another member and it hasn't actually been initialised yet. Really I think the answer is to initialise in the order that initialisation is written (this is what Rust does) rather than declaration order. But that would be a breaking change so I guess they opted for the conservative choice.
- gpderetta 3y agoYes, and there was a strong push to define the order although it ultimately failed. On the other hand evaluation order of aggregate initializers is well defined (left to right) and there was little appetite to weaken it. It might still happen in the future of course.
- calamari4065 3y agoIs `int B = A` even legal? Aren't field initializers like that supposed to be compile time constant?
- nemetroid 3y agoIt's allowed since C++11.
- CamperBob2 3y agoFail to compile due to forward references in initializers. The problem is, someone thought this was a good idea, but the act of supporting it ruled out a lot of more-useful future improvements.