-3

Why instance of class with user defined destructor has member pointer set to zero and class without user-defined destructor does not set default pointer value?

#include <stdio.h>

struct A
{
    int *p;
    ~A(){};
};

struct B
{
    int *p;
};

int main()
{
    A a;
    printf("a.p=%p\n", a.p);

    B b;
    printf("b.p=%p\n", b.p);
}

The output is:

a.p=00000000
b.p=7667ADF9

*using gcc version 3.4.5 (mingw-vista special r3).

jacekmigacz
  • 789
  • 12
  • 22
  • 1
    is the behavior consistent? – Rakib Jun 17 '14 at 08:44
  • 6
    No reason. Pure chance. You can't rely on that behaviour. – juanchopanza Jun 17 '14 at 08:44
  • @Rakibul Hasan Yes. Zero is always zero. Junk is random. – jacekmigacz Jun 17 '14 at 08:45
  • 3
    It is not guaranteed to be zero by the language. It is, as @juanchopanza said, pure chance. – Nawaz Jun 17 '14 at 08:48
  • Your answer: http://stackoverflow.com/a/2418195/2352671 – 101010 Jun 17 '14 at 08:59
  • You are probably getting a value that was on the stack, and by pure chance, the first variable `a` has its internal value on a value that is always left `0x00000000` by the code that runs your main. However, this completely dependent on the implementation that code and it is not defined, and certainly not portable. The proper thing is to initialize the pointers to a defined value in a constructor. – tillaert Jun 17 '14 at 09:01
  • Try [inverting the order of initialization](http://ideone.com/ZS3PzY) and see what happens. – juanchopanza Jun 17 '14 at 09:03
  • @tillaert Alternatively, one can value initialize the instances: `A a{};` (or `A a = A();` in C++03.) – juanchopanza Jun 17 '14 at 09:09
  • @tillaert: You are right. About main function's stack. (and I'm not looking for portable solution. I' just try to explain that behavior). – jacekmigacz Jun 17 '14 at 09:14
  • @juanchopanza: Inverted stack initialization of A and B makes both non-zero. This is good hint. – jacekmigacz Jun 17 '14 at 09:14
  • @jacekmigacz: `A()` is absolutely a default ctor "call" (it's not, actually, but it does cause one). – Lightness Races in Orbit Jun 17 '14 at 09:20

2 Answers2

1

The values are undefined. It's a coincidence that a is zero.

You are getting a value that was on the stack, and by pure chance, the first variable a has its internal value on a value that is always left 0x00000000 by the code that runs your main. However, this completely dependent on the implementation that code and it is not defined, and certainly not portable. The proper thing is to initialize the pointers to a defined value in a constructor or through default initialization.

In answer to your question: There is no difference, you are observing a side effect. If you remove the destructor from A and add one to B the values do not change. (i.e. a.p is still 0)

tillaert
  • 1,797
  • 12
  • 20
  • This is corrent, but it's not full answer. Still, why instance of `struct A { int *p; };` (.p) is aligned to stack address while instance of `struct A { int *p; ~A(){} };` is not. – jacekmigacz Jun 17 '14 at 09:19
  • @jacekmigacz Adding a destructor might change the relative position of the values on the stack, but they are still uninitialized and undefined. – tillaert Jun 17 '14 at 09:28
  • Yes. Allocation of TWO object one after another proves that user-defined destructor does not force zero initialization. – jacekmigacz Jun 17 '14 at 09:32
0

It doesn't. The pointer has an unspecified value. If you're seeing zero then that's just down to pure chance.

Note that reading this uninitialised value actually has undefined behaviour, so you could see a supernova form behind your left eyelid instead of seeing any numbers whatsoever.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055