Hacker News new | past | comments | ask | show | jobs | submit login

Designated Initializers done awkwardly a.k.a. "the C++ way"

  // Point2D point2d {.y = 2, .x = 1};         // (1) error
Oh my. The C++ committee keeps their flight altitude rivaling moles and worms. This is another brittle feature, just like the initializer lists that have to mirror the declaration order. In what world is this a better option than allowing any order? Can't compiler implementors be bothered or what is the rationale?? C does this better.



I think you are confused about the intention. If you want order independent initialization you could just as well use the old initializer list. The idea here is that you DON'T want to accidentally initialize x with y.


I don't think I am confused. The point is that, logically, either you do not tag something with names, and then, naturally, the order decides. Or, you tag something with names, and then, given you named things, there ought to be no order. Not so with the C++ initializers. An initializer list in a constructor should mirror the declaration order, or you won't go warning free. Every time you'd touch the internals of your class, you'd need to touch every constructor that uses an initializer list. Same with the struct initializers now. You are having this:

  struct A { int a, b, c};
you need to do this:

  A a = { .a = 1, .c = 3};
but you can't do this:

  A a = { .c = 3, .a = 1};
because... well, because C++. There is no reason to disallow the second form except for .. what exactly? What is the reasoning of the C++ committee to not be able to mirror what one can do in C (where, aside of the missing typedef or "struct" in front of A, both forms are valid)?

Just as you're saying, the C++ committee seems to be confused about order-dependent and named initializations, and for some love-of-bean-counting insist that named initialization needs to respect order _as well_.


There is of course a reason which is well documented in the papers. Constructors, and initialization expressions can have side effects in C++. An invariant of the language is that member constructors are always invoked in declaration order, so if you were to swap the initializers around, the compiler would still have to initialize them in the original order, which would be surprising.

Which does not means that it couldn't be done, in fact constructor initializer lists have the same issue and you are allowed to list them in any order but this is considered a language mistake and most compilers warn about out of order initializer. This mirror the arbitrary evaluation order of function parameters which is also considered a mistake.

In the end there was no consensus to allowing an arbitrary order, but in the future that can be relaxed without breaking any code if a consensus is reached, while the reverse could not be done.

As usual it is always compromises.

Anyway, at last for me, initializers are more about writing more explicit code and be more robust in the face of changes.


> There is of course a reason which is well documented in the papers. Constructors, and initialization expressions can have side effects in C++. An invariant of the language is that member constructors are always invoked in declaration order, so if you were to swap the initializers around, the compiler would still have to initialize them in the original order, which would be surprising.

The following:

    Point2D pt = {.y = 5, .x = 6};
should not have meant that 'y' is initialized before 'x'. It's only a lexical convenience that exists before parsing. When the code is parsed into an AST, the actual AST would reflect the following code:

    Point2D pt = {.x = 6, .y = 5};
There is absolutely no reason to enforce declaration order.


I tend to agree with ephaeton that forcing the order is a little heavy-handed. But thanks for the insight about initialization order.

For what it's worth, I find strictness pedantry like this fairly useless in production. For example, a JSON file has an order to the elements of an associative array, but Javascript doesn't. So most of the time, I treat associative arrays as having no order, and use another array to map indices to keys or whatever.

Contrast that with PHP, which does maintain key index in the order it's added. There have been countless times where it turned out that I needed that order, and it saved me the work of declaring the extra array. Even more importantly, I've never been hit by that surprise (of not having order) in PHP, whereas I have in pretty much every other language.

So maybe PHP is less pure, but truthfully, pureness is the single biggest source of friction in my daily life. Basically the entirety of my day now goes to setting up environments from minimalist environments, working around subtle language errata, or translating what I want to do in my head to the domain-specific language decisions that are so widespread in languages like Ruby.

I prefer the lazy route now in most things. Just give me everything, with the least-friction needed to do what's in my head, and let me prune it/optimize it when I'm done. So in this case, I'd prefer C++ to have a strict ordering of elements, but let me initialize them in any order, so that I can think in abstractions rather than implementation details. Which is why PHP is roughly 100 times more productive for me than C++, even though I grew up with C++ and know it like the back of my hand.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: