by cyber1 on 7/5/24, 8:42 AM with 226 comments
by gpderetta on 7/5/24, 1:01 PM
T̶h̶a̶t̶ d̶o̶e̶s̶n̶'t̶ s̶e̶e̶m̶ c̶o̶r̶r̶e̶c̶t̶:̶ a̶ d̶e̶f̶a̶u̶l̶t̶e̶d̶ c̶o̶n̶s̶t̶r̶u̶c̶t̶o̶r̶ s̶t̶i̶l̶l̶ d̶e̶f̶a̶u̶l̶t̶-̶i̶n̶i̶t̶i̶a̶l̶i̶z̶e̶s̶ t̶h̶e̶ m̶e̶m̶b̶e̶r̶s̶, n̶o̶t̶ v̶a̶l̶u̶e̶ i̶n̶i̶t̶i̶a̶l̶i̶z̶e̶. I̶ d̶o̶n̶'t̶ t̶h̶i̶n̶k̶ t̶h̶e̶r̶e̶ i̶s̶ a̶n̶y̶ d̶i̶f̶f̶e̶r̶e̶n̶c̶e̶ b̶e̶t̶w̶e̶e̶n̶ d̶e̶f̶a̶u̶l̶t̶i̶n̶g̶ i̶n̶l̶i̶n̶e̶ a̶n̶d̶ o̶u̶t̶ o̶f̶ l̶i̶n̶e̶. G̶C̶C̶ s̶e̶e̶m̶s̶ t̶o̶ a̶g̶r̶e̶e̶:̶ h̶t̶t̶p̶s̶:̶//g̶c̶c̶.g̶o̶d̶b̶o̶l̶t̶.o̶r̶g̶/z̶/r̶4̶r̶e̶5̶T̶E̶5̶a̶
edit: I missed that the author is actually value-initializing x!!! The result definitely violates expectations!
Generally, the details of the rules are arcane and sometimes have non-sensical dark corners having been extended and patched up for the last 40 years. But 99.9%[1] of the time you get what you expect.
I big improvement would be making default initialization explicit, and otherwise always value initialize. Explicit value initialization is so common that the very rare times I want default initialization (to avoid expensively zeroing large arrays) I need to write a fat comment. Writing "std::array<int, 100> = void;" (or whatever the syntax would be) would be much better.
[1] I had an extra 9 here... I hedged.
by nickysielicki on 7/6/24, 2:01 AM
Edit: this response is a bit dismissive but honestly my main beef with this article is that its conclusion is just straight up wrong. Do not write your own constructors, do follow the rule of 5/3/0, and if you find yourself needing to hold a const reference, you should look out for whether you’re passing in an rval temporary… none of this is really scary.
by bookofjoe on 7/5/24, 2:38 PM
https://talesofmytery.blogspot.com/2018/10/harlan-ellison-i-...
by amluto on 7/5/24, 5:02 PM
> So, here’s the glue between list-initialization and aggregate initialization: if list-initialization is performed on an aggregate, aggregate initialization is performed unless the list has only one argument, of type T or of type derived from T, in which case it performs direct-initialization (or copy-initialization).
The word “unless” is even bold.
We have fancy syntax:
T t{v0};
And we also have: T t{v0, v1};
And so on. But the one-element case does not reliably work like the 2+-element case. And this is in a language that increasingly works toward making it straightforward to create a struct from a parameter pack and has support for variable length array-ish things that one can initialize like this. And the types can, of course, be templated.So you can write your own constructors, and you can initialize a tuple or array with only one element supplied, and you might trip over the wrong constructor being invoked in special cases.
I remember discovering this when C++11 initializer lists were brand new and thinking it was nuts.
by AlexandrB on 7/5/24, 2:30 PM
It's 15 years out of date now, but also timeless since C++ rarely/never removes old features or behaviours.
by gattilorenz on 7/5/24, 12:27 PM
by IAmLiterallyAB on 7/6/24, 4:43 AM
I'm hoping something like Herb's C++ syntax 2 will make the language useable for mortals like me.
by jakewins on 7/5/24, 11:50 AM
It’s been a while now, and at least in my experience so far Go and Rusts choice of not having special constructors really simplifies a lot.
Is there anyone that’s had the experience of missing constructors once you swapped away from them?
by jolj on 7/5/24, 3:19 PM
Such as all the constructors that are being added, implicit copy constructor and all the other surprises?
by OptionOfT on 7/5/24, 8:22 PM
T::T() = default;
> You’d expect the printed result to be 0, right? You poor thing. Alas—it will be garbage. Some things can never be perfect, it seems. Here’s a relevant excerpt from our description of value-initialization:Link: https://consteval.ca/2024/07/03/initialization/#:~:text=You%...
That actually isn't that weird, because it would allow any consumer of your library to change how your library behaves.
by marton78 on 7/5/24, 11:54 AM
Kudos to that author for the great, eye catching title and the in depth detail!
by echelon on 7/5/24, 11:56 AM
by kazinator on 7/5/24, 12:47 PM
That can't be right ... is it? Things cannot be initialized twice. Isn't it more like "Otherwise, recurse the value-initialization over the bases and members". Then, those that are not classes or arrays get zero-initialized.
by shadowgovt on 7/5/24, 11:49 PM
For good or for ill, I don't really trust anything that long to be something the average human can wrestle down. And when you mix in undefined behavior and the fact it's still used on safety-critical systems... It's a bit horrifying really.
by wateralien on 7/5/24, 11:58 AM
by pierrebai on 7/5/24, 7:30 PM
So their claim that "T t;" will "do nothing" is incorrect.
class T
{
public:
T(int);
};
T t;
Will fail.by jeffbee on 7/5/24, 4:35 PM
by hwc on 7/5/24, 2:05 PM
I like keeping the rules of the language simple enough that there is never any confusion.
by MathMonkeyMan on 7/6/24, 12:52 AM
by sixtram on 7/5/24, 3:24 PM
by nxobject on 7/5/24, 10:37 PM
by vsgherzi on 7/5/24, 5:17 PM
by gnarlouse on 7/6/24, 1:36 AM
"Call J. G. Wentworth, 877 Cash Now!"
by 3l3ktr4 on 7/5/24, 12:50 PM