views:

414

answers:

7

Code sample should explain things:

class A
{
    B* pB;
    C* pC;
    D d;

    public : 
    A(int i, int j) : d(j)
    {
        pC = new C(i, "abc");
    } // note pB is not initialised, e.g. pB(NULL)

    ...
};

Obviously pB should be initialised to NULL explicitly to be safe (and clear), but, as it stands, what is the value of pB after construction of A? Is it default initialised (which is zero?) or not (i.e. indeterminate and whatever was in memory). I realise initialisation in C++ has a fair few rules.

I think it isn't default initialised; as running in debug mode in Visual Studio it has set pB pointing to 0xcdcdcdcd - which means the memory has been new'd (on the heap) but not initialised. However in release mode, pB always points to NULL. Is this just by chance, and therefore not to be relied upon; or are these compilers initialising it for me (even if it's not in the standard)? It also seems to be NULL when compiled with Sun's compiler on Solaris.

I'm really looking for a specific reference to the standard to say one way or the other.

Thanks.

+1  A: 

I believe this is a artifact from the good old C days when you could not have expectations on what alloc'd memory contains. As the standards progressed to C++ this "convention" was maintained. As the C++ compilers developed the individual authors took it upon themselves to "fix" this problem. Therefore your mileage may vary depending on your compiler of choice.

The "0xcdcdcdcd" looks to be a readily identifiable pattern that "helps" in debugging you code. That is why it doesn't show in release mode.

I hope this helped in a little way and good luck.

Craig
A: 

Uninitialised pointers can point to anything. Some compiler vendors will help you out and make them point to 0 or 0xcdcdcdcd or whatever.

To make sure your code is safe and portable you should always initialise your pointers. either to 0 or to a valid value.

e.g.

C* pc = 0;

or

C* pc = new C(...);

If you always initialise pointers to 0 then this is safe :

if (!pc) 
    pc = new C(...);

If you don't initialise then you've got no way of telling initialised and uninitialised pointers apart.

As an aside, there's no such keyword in C++ as NULL. Most compilers define NULL as 0, but it's not considered portable to use it. The new c++0x standard will introduce a new keyword, nullptr, so when that comes out we'll finally have a portable null pointer constant.

Glen
+1  A: 

The value of pB is undefined. It may or may not be consistently the same value - usually depends on what was previously at the same place in memory prior to the allocation of a particular instance of A.

sean e
+8  A: 

Here is the relevant passage fromt he standard:

12.6.2 Initializing bases and members [class.base.init]

4 If a given nonstatic data member or base class is not named by a mem-
initializer-id in the mem-initializer-list, then

--If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base class, and the entity class is a non-POD class, the entity is default-initialized (dcl.init). If the entity is a nonstatic data member of a const-qualified type, the entity class shall have a user-declared default constructor.

--Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a (possibly cv-quali- fied) POD class type (or array thereof) containing (directly or indirectly) a member of a const-qualified type, the program is ill- formed.

After the call to a constructor for class X has completed, if a member

of X is neither specified in the constructor's mem-initializers, nor
default-initialized, nor initialized during execution of the body of
the constructor, the member has indeterminate value.

Greg Rogers
so it's uninitialized, and can point to anything. THe content may be filled in by the implementation, i.e. fdfdfdfd for the debugheap library.
xtofl
A: 

Uninitialised pointers are allow to basically contain a random value, although some compilers tend to fill them with 0 or some other recognisable value, especially in debug mode.

IMHO this is due to C++'s "don't pay for what you don't use" design. If you don't consider it important, the compiler does not need to go through the expense of initialising the variable for you. Of course, once you've chased a random pointer you might find it prudent to initialise it the next time around...

Timo Geusch
Don't you mean, "*Don't* pay for what you don't use"?
Imagist
Errr.... Yes. Thanks for pointing that out.
Timo Geusch
+2  A: 

According to the C++0x standard section 12.6.2.4, in the case of your pointer variable, if you don't include it in the initializer list and you don't set it in the body of the constructor, then it has indeterminate value. 0xCDCDCDCD and 0 are two possible such values, as is anything else. :-)

Kristo
A: 

It's rare that I'll recommend not learning something about the language you're using, but in this case, whether or not pB is initialized isn't useful information. Just initialize it. If it's automatically initialized, the compiler will optimize out the extra initialization. If it isn't, you've added one extra processor instruction and prevented a whole slew of potential bugs.

Imagist