sizeof with virtual inheritance

Eljay Love-Jensen eljay@adobe.com
Fri May 7 23:42:00 GMT 2004


Hi Adrian,

 >How can I see the layout like that?

I just enhanced your example.

$ cat Adrian.cpp
#include <iostream>

using namespace std;

struct c1{char x; void p1() const;};
struct c2:public c1{void p2() const;};
struct c3:public c1{void p3() const;};
struct c4:virtual public c1{void p4() const;};
struct c5:virtual public c1{void p5() const;};
struct c6:public c2, public c3{void p6() const;};
struct c7:public c4, public c5{void p7() const;};

#define P(x) \
void c##x::p##x() const \
{ \
         cerr << "c" #x ":" << (void*)this << endl; \
}

P(1)
P(2)
P(3)
P(4)
P(5)
P(6)
P(7)


#define S(x) cout<<"c"#x<<": "<<sizeof(c##x)<<endl;

int main()
{
         S(1)S(2)S(4)S(6)S(7)

         cerr << "\nc4...\n";
         c4 o4;
         o4.p1();
         o4.p4();

         cerr << "\nc6...\n";
         c6 o6;
         //o6.p1(); -- ambiguous
         o6.p2();
         o6.p3();
         o6.p6();

         cerr << "\nc7...\n";
         c7 o7;
         //o7.p1(); -- ambiguous
         ((c4&)o7).p1();
         ((c5&)o7).p1();
         o7.p4();
         o7.p5();
         o7.p7();
         //cin.get();
}

 >And what is the actual use of that "pointer for the multiple inheritance 
overhead"?

Multiple inheritance incurs a potential extra level of indirection.

 >What does it point to and when and how is it used?

I believe it points to a class layout map.  When a multiple-inherited 
object is passed to a routine -- especially one that takes one of it's 
parent class types -- it has to take into account that the memory layout 
may be something unexpected.

This descrambling of multiple-inheritance is different from that of the 
virtual function table.  But both have the similarity of adding overhead.

 >Is it possible to disable it, especially that it's at the end of the layout?

Yes, you can disable it using the GCC __attribute__((packed)) 
decoration.  But I strongly suggest you don't do that, since (likely) 
you'll make the class unusable in an array, non-inheritable, and not able 
to be used as a member variable in another class.

And the __attribute__ extension is a GCC-ism.

HTH,
--Eljay



More information about the Gcc-help mailing list