MSVC++ compiler /d1reportSingleClassLayout /d1reportAllClassLayout

Some undocumented parameter in MSVC++ compiler
/d1reportSingleClassLayout<name> and /d1reportAllClassLayout

Example1
// v.cpp

class B
{
public:
int ib;
char cb;
public:
B():ib(0),cb(‘B’) {}

virtual void f() { cout << "B::f()" << endl;}
virtual void Bf() { cout << "B::Bf()" << endl;}
};
class B1 : public B
{
public:
int ib1;
char cb1;
public:
B1():ib1(11),cb1(‘1’) {}

virtual void f() { cout << "B1::f()" << endl;}
virtual void f1() { cout << "B1::f1()" << endl;}
virtual void Bf1() { cout << "B1::Bf1()" << endl;}

};
class B2: public B
{
public:
int ib2;
char cb2;
public:
B2():ib2(12),cb2(‘2’) {}

virtual void f() { cout << "B2::f()" << endl;}
virtual void f2() { cout << "B2::f2()" << endl;}
virtual void Bf2() { cout << "B2::Bf2()" << endl;}

};

class D : public B1, public B2
{
public:
int id;
char cd;
public:
D():id(100),cd(‘D’) {}

virtual void f() { cout << "D::f()" << endl;}
virtual void f1() { cout << "D::f1()" << endl;}
virtual void f2() { cout << "D::f2()" << endl;}
virtual void Df() { cout << "D::Df()" << endl;}

};



E:>cl v.cpp -d1reportSingleClassLayoutD

class D size(48):
+—
| +— (base class B1)
| | +— (base class B)
0 | | | {vfptr}
4 | | | ib
8 | | | cb
| | | <alignment member> (size=3)
| | +—
12 | | ib1
16 | | cb1
| | <alignment member> (size=3)
| +—
| +— (base class B2)
| | +— (base class B)
20 | | | {vfptr}
24 | | | ib
28 | | | cb
| | | <alignment member> (size=3)
| | +—
32 | | ib2
36 | | cb2
| | <alignment member> (size=3)
| +—
40 | id
44 | cd
| <alignment member> (size=3)
+—

D::$vftable@B1@:
| &D_meta
| 0
0 | &D::f
1 | &B::Bf
2 | &D::f1
3 | &B1::Bf1
4 | &D::Df

D::$vftable@B2@:
| -20
0 | &thunk: this-=20; goto D::f
1 | &B::Bf
2 | &D::f2 //f2的this adjustor: 20
3 | &B2::Bf2

D::f this adjustor: 0 //B1和B2都有f,B2的f需要对this-=20,但B1不需要
D::f1 this adjustor: 0
D::f2 this adjustor: 20
D::Df this adjustor: 0

Example2

// v2.cpp

class B
{
public:
int ib;
char cb;
public:
B():ib(0),cb(‘B’) {}

virtual void f() { cout << "B::f()" << endl;}
virtual void Bf() { cout << "B::Bf()" << endl;}
};
class B1 : virtual public B
{
public:
int ib1;
char cb1;
public:
B1():ib1(11),cb1(‘1’) {}

virtual void f() { cout << "B1::f()" << endl;}
virtual void f1() { cout << "B1::f1()" << endl;}
virtual void Bf1() { cout << "B1::Bf1()" << endl;}

};
class B2: virtual public B
{
public:
int ib2;
char cb2;
public:
B2():ib2(12),cb2(‘2’) {}

virtual void f() { cout << "B2::f()" << endl;}
virtual void f2() { cout << "B2::f2()" << endl;}
virtual void Bf2() { cout << "B2::Bf2()" << endl;}

};

class D : public B1, public B2
{
public:
int id;
char cd;
public:
D():id(100),cd(‘D’) {}

virtual void f() { cout << "D::f()" << endl;}
virtual void f1() { cout << "D::f1()" << endl;}
virtual void f2() { cout << "D::f2()" << endl;}
virtual void Df() { cout << "D::Df()" << endl;}

};


E:>cl v2.cpp -d1reportSingleClassLayoutD

class B size(12):
+—
0 | {vfptr}
4 | ib
8 | cb
| <alignment member> (size=3)
+—

B::$vftable@:
| &B_meta
| 0
0 | &B::f
1 | &B::Bf

B::f this adjustor: 0
B::Bf this adjustor: 0


class B1 size(32):
+—
0 | {vfptr}
4 | {vbptr}
8 | ib1
12 | cb1
| <alignment member> (size=3)
+—
16 | (vtordisp for vbase B)
+— (virtual base B)
20 | {vfptr}
24 | ib
28 | cb
| <alignment member> (size=3)
+—

B1::$vftable@B1@:
| &B1_meta
| 0
0 | &B1::f1
1 | &B1::Bf1

B1::$vbtable@:
0 | -4
1 | 16 (B1d(B1+4)B)

B1::$vftable@B@:
| -20
0 | &(vtordisp) B1::f
1 | &B::Bf

B1::f this adjustor: 20
B1::f1 this adjustor: 0
B1::Bf1 this adjustor: 0

vbi: class offset o.vbptr o.vbte fVtorDisp
B 20 4 4 1


class B2 size(32):
+—
0 | {vfptr}
4 | {vbptr}
8 | ib2
12 | cb2
| <alignment member> (size=3)
+—
16 | (vtordisp for vbase B)
+— (virtual base B)
20 | {vfptr}
24 | ib
28 | cb
| <alignment member> (size=3)
+—

B2::$vftable@B2@:
| &B2_meta
| 0
0 | &B2::f2
1 | &B2::Bf2

B2::$vbtable@:
0 | -4
1 | 16 (B2d(B2+4)B)

B2::$vftable@B@:
| -20
0 | &(vtordisp) B2::f
1 | &B::Bf

B2::f this adjustor: 20
B2::f2 this adjustor: 0
B2::Bf2 this adjustor: 0

vbi: class offset o.vbptr o.vbte fVtorDisp
B 20 4 4 1


class D size(56):
+—
| +— (base class B1)
0 | | {vfptr}
4 | | {vbptr}
8 | | ib1
12 | | cb1
| | <alignment member> (size=3)
| +—
| +— (base class B2)
16 | | {vfptr}
20 | | {vbptr}
24 | | ib2
28 | | cb2
| | <alignment member> (size=3)
| +—
32 | id
36 | cd
| <alignment member> (size=3)
+—
40 | (vtordisp for vbase B)
+— (virtual base B)
44 | {vfptr}
48 | ib
52 | cb
| <alignment member> (size=3)
+—

D::$vftable@B1@:
| &D_meta
| 0
0 | &D::f1
1 | &B1::Bf1
2 | &D::Df

D::$vftable@B2@:
| -16
0 | &D::f2
1 | &B2::Bf2

D::$vbtable@B1@:
0 | -4
1 | 40 (Dd(B1+4)B)

D::$vbtable@B2@:
0 | -4
1 | 24 (Dd(B2+4)B)

D::$vftable@B@:
| -44
0 | &(vtordisp) D::f
1 | &B::Bf

D::f this adjustor: 44
D::f1 this adjustor: 0
D::f2 this adjustor: 16
D::Df this adjustor: 0

vbi: class offset o.vbptr o.vbte fVtorDisp
B 44 4 4 1

What is vtordisp for vbase B ?

Thr vtordisp is an offset that is used if you call any virtual functions in the constructor and destructor.

It is used very rarely - but we have to add it to classes that inherit from a virtual base class and override virtual functions just in case the user does call a virtual function in the constructor or destructor.

 

http://msdn.microsoft.com/en-us/library/ms879782.aspx

Enables the addition of the hidden vtordisp construction/destruction displacement member. The vtordisp pragma is applicable only to code that uses virtual bases. If a derived class overrides a virtual function that it inherits from a virtual base class, and if a constructor or destructor for the derived class calls that function using a pointer to the virtual base class, the compiler may introduce additional hidden “vtordisp” fields into classes with virtual bases.

The vtordisp pragma affects the layout of classes that follow it. The /vd0 and /vd1 options specify the same behavior for complete modules. Specifying off suppresses the hidden vtordisp members. Specifying on, the default, enables them where they are necessary. Turn off vtordisp only if there is no possibility that the class’s constructors and destructors call virtual functions on the object pointed to by the this pointer.





end