简体   繁体   中英

Why don't C++ compilers zero-initialize integer, floating-point, and pointer variables by default?

Sometimes, we can use tools like valgrind to find out if we forgot to initialize a pointer variable. But why don't modern compilers relieve us from this common mistake which is hard to reproduce?

Initialization is not always desirable:

  • For performance reasons; initializing memory takes time which may not be necessary. There are even algorithms that depend on constant time allocation to achieve their desired performance (initialization is linear time). D recognizes this but has a different (probably better) approach; variables are initialized by default but has special syntax to prevent initialization.

  • Sometimes there is no correct default value. Static analysis or runtime debugging features can help detect when a variable is used without initialization. Simply assigning some (incorrect) value to them by default could hide a bug that would be detected using these.

There are several aspects to your question. First of all, the standard doesn't mandate this behavior. But where it wouldn't violate the standard it's probably possible. In fact debug builds, eg in MSVC, do quite the opposite and initialize not with 0 but with some magic value - another magic value is used to fill "freed" memory. Again, this is specific to debug builds and can help detect certain classes of errors while it might hide other bugs or obscure there whereabouts in a code base.

But I think the performance issue weighs more here. If you were to initialize integers and floats, why not all kinds of structs or arrays both on the heap and on the stack? The problem with this is of course that if I write my program and allocate a buffer to read data into it, why should I waste time to zero the buffer first if I know I'm going to read x bytes and the buffer is only x bytes long?

I agree, relying on this "random" behavior like in the Debian SSH disaster wasn't correct, but it shows that people rely on the existing behavior and consequences of changes to this behavior will not always be obvious.

Not exactly. Apart from the reasons presented in the other answers, I'd like to point out that:

a) Global variables, static local variables are always initialized, if not explicitly, then implicitly zero.
b) For a custom class `class Test`, creating a new instance by `Test *ptr=new Test()` or `Test test;` gives an initialized object.

To sum up, things that end up in '.data' '.bss' sections of ELF file are initialized either explicitly or implicitly ( zero ). Other variables in primitive types that doesn't lie in the area mentioned above has undefined content before explicit initialization (depends on your compiler). This is because, the ELF file itself provides a way to initialize variables in a) kind at very low cost, while initializing variables in stack, heap, etc, can be a terrible overhead.

You might argue that class Object might be more costly to initialize. But, above all, omitting initialization for primitive types is how things works in C and therefore C++ comply with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM