This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: sizeof with virtual inheritance


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]