Appleshell
Appleshell

Reputation: 7388

Why is the behavior of uninitialized containers different with optimizations?

Given is a class with the following element:

std::array<Class*, 4> children;

In debug mode, checking an element of the uninitialized array on nullptr returns true.

if(children[0]==nullptr)

In release mode (with optimizations enabled, regardless whether O1, O3 or Os) however, the check returns false.

It seems that the elements are somehow initialized, but accessing them still results in a segmentation fault. To avoid this behavior, I have to explicitly initialize the std::array with nullptr elements.

std::array<Class*, 4> children{{nullptr}};

Why is this the case?

Edit: The compiler used in this case is Apple LLVM 4.2 (Xcode 4.6.3).

Upvotes: 1

Views: 166

Answers (4)

JohannesD
JohannesD

Reputation: 14421

std::array is an aggregate, like builtin arrays, so it is not guaranteed to automatically initialize its elements if they aren't of a user-defined type (elements with a user-defined type are default constructed). You cannot rely on the elements having any particular value. In your case, it might be that in debug (non-optimized) mode, it allocates new space from the stack that happens to be already zeroed-out, but with optimizations enabled, the compiler may realize it can reuse space that's not needed anymore, but retains old data.

Upvotes: 3

Mats Petersson
Mats Petersson

Reputation: 129314

Because the content of uninitialized (that aren't of static storage duration) variables is "indeterminate" - not possible to know what it will be, and can vary from one time to another, depending on any number of factors.

Compiler will generate different code for different optimisation levels, which may cause different layout of variables in memory. If you want to see predictable behaviour then you must initialize the variables. Anything else, and it will depend on any number of factors, including optimisation level, what "result" you get.

Upvotes: 1

Martin Schlott
Martin Schlott

Reputation: 4547

In debug mode, the behavior depend on the compiler. Some compiler/debugger set magic values (for e.g. VS uses 0xCDCDCDCD) some uses zero (not good at all). In release mode, memory is not initialized. Thats the reason it may work in debug modus with some compiler, but never in release.

Upvotes: 2

dzada
dzada

Reputation: 5854

Visual may set magic numbers on uninitialized memory. You can not obvious ly test uninitialized memory anyway

Upvotes: 0

Related Questions