C++ Default Constructors

Well the bug I was getting bitten by at work is shown by the following code.

class c1  
  int a;  
  int b;  

class c2  
  int c;  
  int d;  
  c2(): c(3){};  

class c3  
  int e;  
  c1 f;  

class c4  
  int g;  
  c2 h;  

int main(int argc, char* argv[])  
  c1 v1;  
  c2 v2;  
  c3 v3;  
  c4 v4;  

  c1* pv1 = new c1();  
  c2* pv2 = new c2();  
  c3* pv3 = new c3();  
  c4* pv4 = new c4();  

  return 0;  

With a break point on the return (in debug mode). Inspection shows the 8 variables have the follow values:

v1 {a=0xcccccccc b=0xcccccccc }  
v2 {c=0x00000003 d=0xcccccccc }  
v3 {e=0xcccccccc f={a=0xcccccccc b=0xcccccccc } }  
v4 {g=0xcccccccc h={c=0x00000003 d=0xcccccccc } }  
pv1 {a=0x00000000 b=0x00000000 }  
pv2 {c=0x00000003 d=0xcdcdcdcd }  
pv3 {e=0x00000000 f={a=0x00000000 b=0x00000000 } }  
pv4 {g=0xcdcdcdcd h={c=0x00000003 d=0xcdcdcdcd } }  

now v1-v4 are what I’d expect, pv1-pv3 are also are what I’d expect, but pv4 is not!

Because to break the default c3 members values just takes adding a constructor to c1, then c3 is broken.

Both Visual Studio 2003 and Visual Studio 2005 behave the same. It just seems very strange that the existence of a non-default constructor for one member field means that this object (class or struct) doesn’t get a default constructor.

Now I understand the best solution is to never have a struct or class without a constructor, but it just seems so fragile.

The makes extra work for me to upgrade our legacy code base from C malloc to C++ new, as not been able to rely of the default constructor to zero the ram, means I need to manually set all members to zero for all objects.