0

During my work on bringing code from windows-only platform to the GNU compiler I noticed some strange behavior with an uninitialized pointer to a vector.

The corresponding code looks like this:

typedef vector<IPeer*> Network;
// [...]
Network* m_network;
// [...]
if (m_network == NULL)         // <-- this is the strange part
  m_network = new Network();  

The marked line is making me sad. After declaring my vector it was NULL when I compiled it on my Windows machine. After moving the code to my Mac using GNU Compiler (I'm compiling on g++-5 with -std=c++11) my vector doesn't seems to be NULL after declaration anymore. The marked line is skipped.

Is this an c++ standard implementation issue or where does this strange behavior came from?

1
  • @BillLynch Thanks, this is a good in-depth explanation on my issue. Commented Dec 20, 2015 at 17:40

2 Answers 2

2

Uninitialized pointer has undetermined behaviour. Could be NULL or not, depending on the compiler (and, even for a specific compiler, Release and Debug binaries may have a different behaviour) and/or the memory state (see comments to this post).

It is recommended to always initialize them. Never expect an uninitialized variable to have a specific value (it's true for pointers, but also true for other types like int, bool that may take different default initialization values depending on the compiler/target).

It's actually hard to know what will be the value of an unitialized variable, and in many cases it is not deterministic.

Sign up to request clarification or add additional context in comments.

5 Comments

Ok, so it's really depending on the compiler. Thanks!
@Marschal : Contrary to what jpo32 has stated, it does not depend on the compiler at all; it simply depends on what happens to be in that memory location when the variable is instantiated which in turn depends on the previous content of the stack, and there fore previously executed code. A change in any code that runs prior to this (including changes in code generation due to compiler options) could result in a change in behaviour. Zero is a value that occurs a lot in computing, so often the value just happens to be null - that's the "luck" part.
@Clifford: It's perfectly legal for a compiler to generate code that initializes all uninitialized pointer to null -- or, more usefully, to some known invalid value like (void*)0xDEADBEEF. Also, uninitialized pointers with static storage duration (defined outside any function or with the static keyword) are initialized to null.
@KeithThompson : OK, instead of saying that "it does not depend on the compiler at all", perhaps it would be better to caution that, it may be compiler dependent, or it may be entirely non-deterministic. In my observation of compilers (primarily in embedded systems), it is perhaps common for the entire stack to be initialised to some value, but implicit initialisation of individual local variables does not occur. Consequently, early in execution local variables have a deterministic value, but when that stack memory is reused, it has whatever was left there.
Thanks to both of you for the clarification, I edited my post.
1

Local POD variables are initialised by implicitly. In your Windows implementation it just happened to be null by dumb luck and is dangerous code.

Use explicit initialisation:

Network* m_network = 0 ;

2 Comments

Default initialization occurs, it's just that for POD objects, that means to leave the internal state as uninitialized. en.cppreference.com/w/cpp/language/default_initialization
@BillLynch : I changed the wording. I meant "not initialised by default" rather than "default initialisation" which of course has specific meaning in the language definition.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.