Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / June 2004

Tip: Looking for answers? Try searching our database.

virtual-multiple inheritance. what an extra dword is for?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Vladimir_petter - 21 Jun 2004 18:49 GMT
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.

   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ÿ1, sizeof(A)=8      sizeof(vtable) + sizeof(ma_)
   mbÿ2, sizeof(B)      sizeof(vtable) + sizeof(mb_) + 1*sizeof(DWORD) + sizeof(A)
   mcÿ3, sizeof(C)      sizeof(vtable) + sizeof(mb_) + 1*sizeof(DWORD) + sizeof(A)
   mdÿ4, sizeof(D)=8      sizeof(vtable) + sizeof(md_)
   meÿ5, sizeof(E)@    
   &before - &after = 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=" << ma_ << ", sizeof(A)=" << 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=" << mb_ << ", sizeof(B)=" << 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=" << mc_ << ", sizeof(C)=" << 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=" << md_ << ", sizeof(D)=" << dec << sizeof(D) << "\n";
}

class E : public B, public C, public D {
public:
   explicit E(long ma=0xFF1, long mb=0xFF2, long mc=0xFF3, long md=0xFF4, long me=0xFF5)
       : 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=" << me_ << ", sizeof(E)=" << dec << sizeof(E) << "\n";
}

int main(int, char **) {
   cout << hex;

   int distance = 0;
   int before = 0xFE1;

   E e;
   if(!distance) { //to prevent compiler from rearanging veriables on the stack
       int after = 0xFE2;
       distance = &before - &after;
   }
   e.foo();

   cout << dec << "&before - &after = "  << abs(distance) << "\n";

   return 0;
}
Doug Harrison [MVP] - 21 Jun 2004 19:22 GMT
>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.
>
>    Anybody has any idea what this dword is for?

See if this article helps you figure it out:

C++: Under the Hood
Jan Gray
http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarvc/html/jan
grayhood.asp


Signature

Doug Harrison
Microsoft MVP - Visual C++

Vladimir_petter - 21 Jun 2004 21:37 GMT
Hello Doug,

Thanks for the link. It definetly helped.
I am still not 100% sure, but my guess is that this DWORD is a reservaton for a future vbtable to store deplacement of A relative to E.
See bellow corrected picture.

Thanks,
Vladimir.


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'   << deplacement info for A relative to B-------------   |
   05 0012fec0  00000ff2                    << e.mb_, start of E::b                            |   |
   06 0012fec4  0041f17c t11!E::`vbtable'   << deplacement info for A relative to C--------    |   |
   07 0012fec8  00000ff3                    << e.mc_                                      |    |   |
   08 0012fecc  00000ff5                    << e.me_                                      |    |   |
   09 0012fed0  00000000                    << ?is this a reservation for future vbtable? |    |   |
   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"                       |  |    |   |
                                                                                       |  |    |   |
                                                                                       |  |    |   |
t11!E::`vftable' at 0041f174                                                           <-  |    |   |
   0041f174  0040112c t11!ILT+295(?fooE$4PPPPPPPMCAAEXXZ)---------------------------      |    |   |
                                                                                   |      |    |   |
t11!E::`vftable' at 0041f178:                                                       |      |    |   |
   0041f178  004012f3 t11!ILT+750(?fooEUAEXXZ)---------------------------------    |      |    |  <-
                                                                              |    |      |    |  
t11!E::`vbtable' at 0041f17c                                                   |    |     <-    |
   0041f17c  00000000                                                         |    |           |
   0041f180  00000010 << decimal 16, 4 dwords from C to A in E                |    |           |
   0041f184  00000000                                                         |    |           |
                                                                              |    |           |
t11!E::`vbtable' at 0041f188                                                   |    |          <-
   0041f188  00000000                                                         |    |
   0041f18c  00000018 << decimal 24, 6 dwords from B to A in E                |    |
   0041f190  00000000                                                         |    |
                                                                              |    |
t11!ILT+295(?fooE$4PPPPPPPMCAAEXXZ):                                           |   <-
   0040112c e98f540000       jmp     t11!E::foo (004065c0)--                  |
                                                           |                  |
t11!E::foo:                                                <-                  |
   004065c0 2b49fc           sub     ecx,[ecx-0x4]                            |
   004065c3 83e920           sub     ecx,0x20                                 |
   004065c6 e928adffff       jmp     t11!ILT+750(?fooEUAEXXZ) (004012f3)--    |
                                                                         |    |
t11!ILT+750(?fooEUAEXXZ):                                                <-   <-
   004012f3 e9e8040000       jmp     t11!E::foo (004017e0)--                    
                                                           |
t11!E::foo [t11.cpp @ 117]:                                <-
   004017e0 55               push    ebp
   004017e1 8bec             mov     ebp,esp
   004017e3 51               push    ecx
   004017e4 894dfc           mov     [ebp-0x4],ecx
   004017e7 8b45fc           mov     eax,[ebp-0x4]

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.