This is a multi-part message in MIME format.
------=_NextPart_000_002C_01C4577D.73E543F0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hello All,
I've fount that if I compile the same program using gcc and vc 2003 =
the same class E (see complete source bellow) has different size (on vc =
it is 4 bytes bigger). Digging into this I've found that vc is reserving =
a dword in the E class right before storage for virtual base class. In =
my tests value of this dword always was 0. I did not see any code =
referencing this memory.=20
Anybody has any idea what this dword is for?
Vladimir.
/*
Compile:
cl -EHsc -Zi t11.cpp
Classes hierarchy
A
/ \
| |
| |
B D C
| | |
| | |
\ | /
E
Output: My Interpritation:
ma=3Dff1, sizeof(A)=3D8 sizeof(vtable) + sizeof(ma_)
mb=3Dff2, sizeof(B)=3D20 sizeof(vtable) + sizeof(mb_) + =
1*sizeof(DWORD) + sizeof(A)
mc=3Dff3, sizeof(C)=3D20 sizeof(vtable) + sizeof(mb_) + =
1*sizeof(DWORD) + sizeof(A)
md=3Dff4, sizeof(D)=3D8 sizeof(vtable) + sizeof(md_)
me=3Dff5, sizeof(E)=3D40 =20
&before - &after =3D 13
Layout of the stack in the "main" function:
Nr Address Value Points to My Interpritation
01 0012feb0 00000fe2 << veriable "after"
02 0012feb4 0041f178 t11!E::`vftable' << veriable e, start of E, =
start of E::D
03 0012feb8 00000ff4 << e.md_
04 0012febc 0041f188 t11!E::`vbtable' << start of E::B
05 0012fec0 00000ff2 << e.mb_
06 0012fec4 0041f17c t11!E::`vbtable' << start of E::C
07 0012fec8 00000ff3 << e.mc_
08 0012fecc 00000ff5 << e.me_
09 0012fed0 00000000 << ???WHAT ARE THIS FOR???
10 0012fed4 0041f174 t11!E::`vftable' << start of E::A
11 0012fed8 00000ff1 << e.ma_, end of E
12 0012fedc 0000000c << veriable "distance"
13 0012fee0 00000fe1 << veriable "before"
*/
#include<iostream>
using namespace std;
class A {
public:
explicit A(long ma)
: ma_(ma) {
}
virtual void foo();
private:
long ma_;
};
void A::foo() {
cout << hex << "ma=3D" << ma_ << ", sizeof(A)=3D" << dec << =
sizeof(A) << "\n";
}
class B : public virtual A {
public:
explicit B(long mb)
: mb_(mb), A(0) {
}
virtual void foo();
private:
long mb_;
};
void B::foo() {
cout << hex << "mb=3D" << mb_ << ", sizeof(B)=3D" << dec << =
sizeof(B) << "\n";
}
class C : public virtual A {
public:
explicit C(long mc)
: mc_(mc), A(0) {
}
virtual void foo();
private:
long mc_;
};
void C::foo() {
cout << hex << "mc=3D" << mc_ << ", sizeof(C)=3D" << dec << =
sizeof(C) << "\n";
}
class D {
public:
explicit D(long md)
: md_(md) {
}
virtual void foo();
private:
long md_;
};
void D::foo() {
cout << hex << "md=3D" << md_ << ", sizeof(D)=3D" << dec << =
sizeof(D) << "\n";
}
class E : public B, public C, public D {
public:
explicit E(long ma=3D0xFF1, long mb=3D0xFF2, long mc=3D0xFF3, long =
md=3D0xFF4, long me=3D0xFF5)
: A(ma), B(mb), C(mc), D(md), me_(me) {
}
virtual void foo();
private:
long me_;
};
void E::foo() {
A::foo();
B::foo();
C::foo();
D::foo();
cout << hex << "me=3D" << me_ << ", sizeof(E)=3D" << dec << =
sizeof(E) << "\n";
}
int main(int, char **) {
cout << hex;
int distance =3D 0;
int before =3D 0xFE1;
E e;
if(!distance) { //to prevent compiler from rearanging veriables on =
the stack
int after =3D 0xFE2;
distance =3D &before - &after;
}
e.foo();
cout << dec << "&before - &after =3D " << abs(distance) << "\n";
return 0;
}
------=_NextPart_000_002C_01C4577D.73E543F0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2800.1400" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face=3DCourier size=3D2>Hello All,</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> I've fount that if =
I compile=20
the same program using gcc and vc 2003 the same class E =
(see complete=20
source bellow) has different size (on vc it is 4 bytes bigger). Digging =
into=20
this I've found that vc is reserving a dword in the E class right before =
storage=20
for virtual base class. In my tests value of this dword always was 0. I =
did not=20
see any code referencing this memory. </FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> Anybody has any =
idea what this=20
dword is for?</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Vladimir.</FONT></DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>/*</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Compile:<BR> cl =
-EHsc -Zi=20
t11.cpp</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Classes=20
hierarchy<BR> =
A<BR> =20
/ \<BR> | =20
|<BR> | =
|<BR> =20
B D C<BR> | | =20
|<BR> | | |<BR> \ =
|=20
/<BR> E</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier=20
size=3D2>Output: &nb=
sp; =20
My Interpritation:</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> ma=3Dff1,=20
sizeof(A)=3D8 sizeof(vtable) +=20
sizeof(ma_)<BR> mb=3Dff2, =
sizeof(B)=3D20 =20
sizeof(vtable) + sizeof(mb_) + 1*sizeof(DWORD) + =
sizeof(A)<BR> =20
mc=3Dff3, sizeof(C)=3D20 sizeof(vtable) + =
sizeof(mb_) +=20
1*sizeof(DWORD) + sizeof(A)<BR> md=3Dff4,=20
sizeof(D)=3D8 sizeof(vtable) +=20
sizeof(md_)<BR> me=3Dff5, =
sizeof(E)=3D40 =20
<BR> &before - &after =3D 13</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>Layout of the stack in the "main"=20
function:</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> Nr =
Address =20
Value Points=20
to My=20
Interpritation<BR> 01 0012feb0 =20
00000fe2  =
; =20
<< veriable "after"</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> 02 0012feb4 =
0041f178=20
t11!E::`vftable' << veriable e, start of E, start of=20
E::D<BR> 03 0012feb8 =20
00000ff4  =
; =20
<< e.md_<BR> 04 0012febc 0041f188=20
t11!E::`vbtable' << start of =
E::B<BR> 05=20
0012fec0 =20
00000ff2  =
; =20
<< e.mb_<BR> 06 0012fec4 0041f17c=20
t11!E::`vbtable' << start of =
E::C<BR> 07=20
0012fec8 =20
00000ff3  =
; =20
<< e.mc_<BR> 08 0012fecc =20
00000ff5  =
; =20
<< e.me_<BR> 09 0012fed0 =20
00000000  =
; =20
<< ???WHAT ARE THIS FOR???<BR> 10 0012fed4 =
0041f174 t11!E::`vftable' << start of=20
E::A<BR> 11 0012fed8 =20
00000ff1  =
; =20
<< e.ma_, end of E<BR> 12 0012fedc =20
0000000c  =
; =20
<< veriable "distance"</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> 13 0012fee0 =20
00000fe1  =
; =20
<< veriable "before"</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>*/</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>#include<iostream></FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>using namespace std;<BR><BR>class A=20
{<BR>public:<BR> explicit A(long=20
ma)<BR> : ma_(ma)=20
{<BR> }<BR> virtual void=20
foo();<BR>private:<BR> long ma_;<BR>};</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>void A::foo() {<BR> =
cout=20
<< hex << "ma=3D" << ma_ << ", sizeof(A)=3D" =
<< dec=20
<< sizeof(A) << "\n";<BR>}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>class B : public virtual A=20
{<BR>public:<BR> explicit B(long=20
mb)<BR> : mb_(mb), A(0)=20
{<BR> }<BR> virtual void=20
foo();<BR>private:<BR> long mb_;<BR>};</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>void B::foo() {<BR> =
cout=20
<< hex << "mb=3D" << mb_ << ", sizeof(B)=3D" =
<< dec=20
<< sizeof(B) << "\n";<BR>}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>class C : public virtual A=20
{<BR>public:<BR> explicit C(long=20
mc)<BR> : mc_(mc), A(0)=20
{<BR> }<BR> virtual void=20
foo();<BR>private:<BR> long mc_;<BR>};</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>void C::foo() {<BR> =
cout=20
<< hex << "mc=3D" << mc_ << ", sizeof(C)=3D" =
<< dec=20
<< sizeof(C) << "\n";<BR>}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>class D =
{<BR>public:<BR> =20
explicit D(long md)<BR> : =
md_(md)=20
{<BR> }<BR> virtual void=20
foo();<BR>private:<BR> long md_;<BR>};</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>void D::foo() {<BR> =
cout=20
<< hex << "md=3D" << md_ << ", sizeof(D)=3D" =
<< dec=20
<< sizeof(D) << "\n";<BR>}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>class E : public B, public C, public =
D=20
{<BR>public:<BR> explicit E(long ma=3D0xFF1, long =
mb=3D0xFF2, long=20
mc=3D0xFF3, long md=3D0xFF4, long=20
me=3D0xFF5)<BR> : A(ma), =
B(mb), C(mc),=20
D(md), me_(me) {<BR> }<BR> virtual =
void=20
foo();<BR>private:<BR> long me_;<BR>};</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>void E::foo() {<BR> =
A::foo();<BR> B::foo();<BR> =20
C::foo();<BR> D::foo();<BR> cout =
<<=20
hex << "me=3D" << me_ << ", sizeof(E)=3D" << dec =
<<=20
sizeof(E) << "\n";<BR>}</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2>int main(int, char **) =
{<BR> =20
cout << hex;</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> int distance =3D=20
0;<BR> int before =3D 0xFE1;</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> E =
e;<BR> =20
if(!distance) { //to prevent compiler from rearanging veriables on the=20
stack<BR> int after =3D=20
0xFE2;<BR> distance =3D =
&before -=20
&after;<BR> }<BR> =
e.foo();</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> cout << dec =
<<=20
"&before - &after =3D " << abs(distance) <<=20
"\n";</FONT></DIV>
<DIV><FONT face=3DCourier></FONT> </DIV>
<DIV><FONT face=3DCourier size=3D2> return=20
0;<BR>}</FONT></DIV></BODY></HTML>
------=_NextPart_000_002C_01C4577D.73E543F0--