Well the bug I was getting bitten by at work is shown by the following code.
class c1
{
public:
int a;
int b;
};
class c2
{
public:
int c;
int d;
c2(): c(3){};
};
class c3
{
public:
int e;
c1 f;
};
class c4
{
public:
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.
*GRRR*