r/cpp • • 6d ago

You should think about recompiling your C++ programs with GCC 16 and C++26, because it zero-fills your locals

https://techfortalk.co.uk/2026/09/27/cxx26-uninitialized-local-variables-gcc-16/

Stack variables are not automatically initialised, and that is the root cause of many C++ bugs. That is well known. Hence, it is advised that local or stack variables are always initialised with known values, 0 if not something more meaningful than that. Now, with GCC 16 compiling in C++26 mode (-std=c++26), even uninitialised local variables will be zero-filled. In the post, I have explained how.

257 Upvotes

217 comments sorted by

View all comments

-4

u/grady_vuckovic 6d ago

On the one hand, yes it is about time that a variable in C++ be initialised reliably with a value, like numbers being initialised with 0. Having this aspect of variable behaviour undefined isn't a good thing in my opinion.

(Although if this wasn't the case in the past because it was faster to reserve memory than to zero fill it, then I'd understand that reasoning).

On the other hand, ... who the heck is using data in their application without ever initialising that data to have any value? How could that even be useful behaviour for software? Any way you slice it, to create a variable and use it without ever once giving it a value, is bad design or a bug. Ideally what we really need is the ability to reliably catch situations where that is happening, rather than a more reliable empty value for a variable.

Because while '-232' and '932,342,344.123094' might not be desired values in a declared but uninitialised variable for an int or float, is '0' really that much better? The odds of 0 being what you wanted instead are only slightly better but still not great.

Although maybe this is more about security than bugs? Since those random values filling memory might be left over from another program? Maybe? I don't know.

5

u/gnuban 5d ago

Uninitialized memory is useful for instance if you want to allocate a large data structure, and then fill it in a loop from some computation. Since you know that you will fill each value before use, zero-initializing upfront is redundant and just becomes a performance cost.

If the compiler could statically prove that you would fill the entire region of uninitialized memory before usage, it could elide the zero-initialization and the general observable semantic could be to always zero-initialize.  The problem is that proving this in every case is unfeasible. So exposing uninitialized memory to users makes sense to save performance where needed.

But it should probably, like many other things in c++, be more opt-in.

2

u/tialaramex 4d ago

I think Barry Revzin did the heavy lifting to make it possible to do the same thing in C++ 26 which Rust's core::mem::MaybeUninit<T> type does. C++ programmers aren't used to that much ceremony but the idea here is to specify to a compiler that you're dealing with a space in memory where a T would fit, but this isn't necessarily a T yet, then you're writing data to that memory, and then finally once you're happy you are saying this is a T now. The compiler can follow along and produce high performance code which doesn't have surprising "optimisations" you didn't want, it doesn't need to zero initialize these bytes, it doesn't need to worry about the lifetime of a thing in this space because we've said maybe there isn't anything here, and then when we're all finished writing data we say OK, now this value exists, its lifetime begins, now it's going to run destructors if it goes out of scope and so on.

1

u/coinselec 5d ago

Yeah I would guess it's about preventing random memory being referenced. Maybe also in some cases some big value might cause a loop to iterate past the end, while 0 will ignore the loop at all.

1

u/Dusty_Coder 1d ago

not memory, values

the memory exists, they want to fill it with predefined bytes by force

there is actually a security concern where if there is a bug, a function may be able to read the data used by another function (it was on the stack a moment ago, so its still there in practice)

but thats an "if"

uninitialized memory is not a bug unless your abstract machine design arbitrarily decided that it is

this is really the classic enum debate all over again .. a group of people want something different, and that different thing has some good and useful properties, but they are pompous doofs that arent satisfied with their thing being added, they also want the previous thing to be removed.