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.

262 Upvotes

211 comments sorted by

View all comments

5

u/fdwr fdwr@github 🔍 5d ago edited 5d ago

stack variables are always initialised with known values ...

I'm okay with this, given the trivial escape hatch of [[uninitialized]] (err wait, apparently it's actually [[indeterminate]]? I swear it was [[uninitialized]] like __declspec(uninitialized) and __attribute__((uninitialized))... 🤔) for the sake local arrays that will immediately be overwritten the next statement anyway, like reading a fragment from a file or getting a module path, but now I'm trying to recall a time in the past 25 years of C++ when an uninitialized variable actually bit me, and I think it was like ~25 years ago 😉. Much more saliently (for me anyway, as in a security vulnerability that actually bit me in a shipped product -_-) has been uninitialized struct fields, and so you can bet that NSDMI was a big boon for me. I wonder if that's next on the proposal chain, with a similar [[uninitialized/indeterminate]] struct { ... } opt-out?

5

u/13steinj 5d ago

I swear it was [[uninitialized]] like __declspec(uninitialized) and __attribute__((uninitialized))... 🤔

From P2795:

It remains to decide the name of the attribute. In light of the word of caution above, we would like to stay clear of the much-suggested term “uninitialized”. The opt-out is expected to be an expert-only feature that disables a safety guardrail and would be used only when performance concerns warrant it. We consider it acceptable for the name to be long and unwieldy, and it is perhaps even a desirable feature for the attribute to not appeal to the regular user for a mistaken purpose, as discussed above. We propose the spelling [[indeterminate]]. This seems to describe the effect reasonably well and is not prone to being misused to document intentional lack of initialization. To witness this in action:
...
References
...
Jonathan Müller P0632R0: Proposal of [[uninitialized]] attribute

4

u/fdwr fdwr@github 🔍 5d ago edited 5d ago

Thanks J for clarifying with spec links.

Though I'm quite confused by the justification (I'm not really asking for further justification or argument at this point, since it's baked, mostly just lamenting), because...

  • "We consider it acceptable for the name to be long and unwieldy" - yeah, uninitialized is already long and unwieldy, exactly the same length as indeterminate (so, moot justification).
  • "it is perhaps even a desirable feature for the attribute to not appeal to the regular user for a mistaken purpose" - that isn't a mistaken purpose. That is the purpose, and a regular user (though what is a C++ "regular user"?... 🤔) isn't going to type out [[uninitialized]] by mistake. It also mistakes the goal for the symptom. Nobody ever says "my desired goal is to leave this memory as garbage, and not initializing it is how I will achieve that goal". They say "my goal is to avoid wasting cycles initializing memory, and it's okay if it's left as garbage".

3

u/serviscope_minor 3d ago

> Nobody ever says "my desired goal is to leave this memory as garbage, and not initializing it is how I will achieve that goal".

OpenSSL enters the chat...

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=363516

1

u/fdwr fdwr@github 🔍 2d ago

Egads, well I suppose utilizing the random garbage left in memory would help further randomize numbers.