5 ms·
Yes but it’s not portable. If zero initialization were the default and you had to opt-in with [[uninitialized]] for each declaration it’d be a lot safer. Unfort
by Matheus28 1y ago
Yes but it’s not portable. If zero initialization were the default and you had to opt-in with [[uninitialized]] for each declaration it’d be a lot safer. Unfortunately I don’t think that will happen any time soon.
- loeg 1y agoI don't really care if it isn't portable. I only have to work with Clang, personally. > If zero initialization were the default and you had to opt-in with [[uninitialized]] for each declaration it’d be a lot safer. I support that, too. Just seems harder than getting a flag into Clang or GCC.
- ryandrake 1y agoPortability is always for the other guy’s sake, not your own. That’s why so many people don’t care about it.
- loeg 1y agoAgain, I'm not opposed to the idea, it just seems more challenging logistically.
- motorest 1y ago> I don't really care if it isn't portable. You don't care because your job is not to ensure that a new release of C++ doesn't break production code. You gaze at your navel and pretend that's the universe everyone is bound to. But there are others using C++, and using it in production software. Some of them care, and your subjective opinions don't have an impact in everyone else's requirements. > I only have to work with Clang, personally. Read Clang's manual and check what compiler flags you need to flip to get that behavior. It's already there.
- loeg 1y agoLmao. You've misread both of my upthread comments and have somehow arrived at the conclusion that this justifies personal attacks. There's just no discussion to be had here.
- TuxSH 1y agoGcc already has [[gnu::uninitialized]] (clang doesn't, AFAIK), as well as -ftrivial-auto-var-init=pattern which exactly matches the new C++26 semantics, if I'm not mistaken
- loeg 1y ago> -ftrivial-auto-var-init=pattern I believe this only helps for trivial automatic variables; not non-trivial automatic variables (structs/classes) that contain uninitialized trivial members.
- TuxSH 1y agoAh, you're right, thanks for correcting me! This also doesn't apply to heap-allocated variables, though I think p2795r2 should cover all these cases. I wonder if (for stack variables) this is due to an implementation detail in the compiler. After all, non-trivial classes have 'actual' constructors that run and that is supposed to initialize their respective class instances...
- tialaramex 1y agoYou probably don't want zero initialization if you can help it. Ideally, what you want is what Rust and many modern languages do: programs which don't explain what they wanted don't compile, so, when you forget to initialize that won't compile. A Rust programmer can write "Don't initialize this 1024 byte buffer" and get the same (absence of) code but it's a hell of a mouthful - so they won't do it by mistake. The next best option, which is what C++ 26 will ship, is what they called "Erroneous Behaviour". Under EB it's defined as an error not to initialize something you use but it is also defined what happens so you can't have awful UB problems, typically it's something like the vendor specifies which bit pattern is written to an "unintialized" object and that's the pattern you will observe. Why not zero? Unfortunately zero is too often a "magic" value in C and C++. It's the Unix root user, it's often an invalid or reserved state for things. So while zero may be faster in some cases, it's usually a bad choice and should be avoided.
- motorest 1y ago> Ideally, what you want is what Rust and many modern languages do: programs which don't explain what they wanted don't compile, so, when you forget to initialize that won't compile. I think you're confusing things. You're arguing about static code analysis being able to identify uninitialized var reads. All C++ compilers already provide support for flags such as -Wuninitiaized.
- dwattttt 1y ago> You're arguing about static code analysis being able to identify uninitialized var reads. (Safe) Rust does guarantee to identify uninitialised variable reads, but I believe the point is that you can get the optimisation of not forcing early initialisation in Rust, you just have to be explicit that that's what you want (you use the MaybeUninit type); you're forced to be clear that that's what you meant, not just by forgetting parens.
- tialaramex 1y agoYou can even write e.g. this: let mut jim: Goat; // Potentially much later ... if some_reason { jim = make_a_new_goat(); } else { jim = get_existing_goat(); } use(jim); // In some way we use that goat now The compiler can see OK, we eventually initialized this variable before we used it, there's no way we didn't initialize it so that's fine, this compiles. But, if we screw up and make it unclear whether jim is initialized, probably because in some cases it wouldn't be - that doesn't compile. This is the usual "avoid early initialization" C++ programmers are often thinking of and it doesn't need MaybeUninit, since it's definitely fine if you're correct, it's just that the C++ compiler is happy (before C++ 26) with just having Undefined Behaviour if you make any mistakes and the Rust compiler will reject that. [Idiomatically this isn't good Rust, Rust is an expression language so we can just write all that conditional if-else block in the initializer itself and that's nicer, but if you're new to this the above works fine.]
- leni536 1y agoSomething like that is heading into C++26 actually. Except the initialization is not to zero, but to some unspecified value (with explicit intention of not allowing leaking garbage) and allowing to trap. It's called "erroneous values".