1

Source Code

class W
{
public:
 virtual void f() { cout << "W::f()" << endl; }
 virtual void g() { cout << "W::g()" << endl; }
};

class AW : public virtual W
{
public:
 void g() { cout << "AW::g()" << endl; }
};


class BW : public virtual W
{
public:
 void f() { cout << "BW::f()" << endl; }
};

class CW : public AW, public BW
{
};

g++ -fdump-class-hierarchy

Vtable for W  
W::_ZTV1W: 4u entries  
0     (int (*)(...))0  
4     (int (*)(...))(& _ZTI1W)  
8     W::f
12    W::g


Vtable for AW  
AW::_ZTV2AW: 7u entries  
0     0u  
4     0u  
8     0u  
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2AW)  
20    W::f  
24    AW::g

VTT for AW  
AW::_ZTT2AW: 2u entries  
0     ((& AW::_ZTV2AW) + 20u)  
4     ((& AW::_ZTV2AW) + 20u)  


Vtable for BW  
BW::_ZTV2BW: 7u entries  
0     0u  
4     0u  
8     0u  
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2BW)  
20    BW::f  
24    W::g  

VTT for BW  
BW::_ZTT2BW: 2u entries  
0     ((& BW::_ZTV2BW) + 20u)  
4     ((& BW::_ZTV2BW) + 20u)  

Vtable for CW  
CW::_ZTV2CW: 14u entries  
0     0u  
4     0u  
8     4u  
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2CW)  
20    BW::_ZTv0_n12_N2BW1fEv  
24    AW::g  
28    4294967292u  
32    4294967292u  
36    0u  
40    (int (*)(...))-0x00000000000000004  
44    (int (*)(...))(& _ZTI2CW)  
48    BW::f  
52    0u  

Construction vtable for AW (0xb6dbf8c0 instance) in CW  
CW::_ZTC2CW0_2AW: 7u entries  
0     0u  
4     0u  
8     0u  
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2AW)  
20    W::f  
24    AW::g  

Construction vtable for BW (0xb6dbf900 instance) in CW  
CW::_ZTC2CW4_2BW: 13u entries  
0     4294967292u  
4     4294967292u  
8     0u  
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2BW)  
20    BW::f  
24    0u  
28    0u  
32    4u  
36    (int (*)(...))4  
40    (int (*)(...))(& _ZTI2BW)  
44    BW::_ZTv0_n12_N2BW1fEv  
48    W::g  

VTT for CW  
CW::_ZTT2CW: 7u entries  
0     ((& CW::_ZTV2CW) + 20u)  
4     ((& CW::_ZTC2CW0_2AW) + 20u)  
8     ((& CW::_ZTC2CW0_2AW) + 20u)  
12    ((& CW::_ZTC2CW4_2BW) + 20u)  
16    ((& CW::_ZTC2CW4_2BW) + 44u)  
20    ((& CW::_ZTV2CW) + 20u)  
24    ((& CW::_ZTV2CW) + 48u)  

Questions

What are each of the entries in:

Vtable for AW  
AW::_ZTV2AW: 7u entries  
0     0u          // whats this for???   
4     0u          // ?  
8     0u          // ?  


Vtable for CW  
CW::_ZTV2CW: 14u entries  
0     0u          // ? 
4     0u          // ?     
8     4u          // what is the significance of this ???    
12    (int (*)(...))0  
16    (int (*)(...))(& _ZTI2CW)  
20    BW::_ZTv0_n12_N2BW1fEv   // ?  
24    AW::g  
28    4294967292u   // ?  
32    4294967292u   // ?  
36    0u            // ?  
40    (int (*)(...))-0x00000000000000004  // some delta   
44    (int (*)(...))(& _ZTI2CW)  
48    BW::f  
52    0u  // ?  


CW *pcw = new CW;  
AW *paw = pcw;  
paw->f();  // Invokes B::f why not w::f

paw is pointing to AW's vtable and it has a entry of W::f. How does B::f() get called?

Similarly:

 BW* pbw = pcw;  
 pbw->g();  // invokes AW::g() why not w::g  ???

What is the use of VTT and how its used. VTT of AW contains pointer to vtable of AW
AW::_ZTT2AW: 2u entries
0 ((& AW::_ZTV2AW) + 20u)
4 ((& AW::_ZTV2AW) + 20u)
and both entries at offset 0 and 4 points to vtable base address+20 u = W::f. Why both the entries point to same function of the base class?

Ganesh Kundapur
  • 525
  • 1
  • 6
  • 13
  • 2
    Related: http://stackoverflow.com/questions/4609631/deciphering-vtable-dumps/4609777#4609777 – templatetypedef Jan 07 '11 at 22:44
  • @trojanfoe I think because he wrote "Thanks" in the end of the question. – Narek Jan 07 '11 at 23:06
  • forgot to mark it earlier. Now i did for all – Ganesh Kundapur Jan 07 '11 at 23:08
  • @trojanfoe: because, believe it or not, some people answer questions to be helpful, not to gain the most virtual monopoly money possible. The real question is why people who care so much about gaining rep, and nothing else, aren't off playing WoW or something where they have a proper game to support their quest for making numbers grow bigger. – jalf Jan 07 '11 at 23:14
  • @jaff you are right, of course, but reputation is a reward which makes helping others more appealing; do you think there would be so many answers if there wasn't the rep reward? There is also a competitive edge to answering questions and finally it's reasonable to be thanked properly for your help – trojanfoe Jan 07 '11 at 23:20
  • @templatetypedef: I went through the related link that you mentioned before posting. Posted as i haven't got my answers from that – Ganesh Kundapur Jan 07 '11 at 23:28
  • "paw is pointing to AW's vtable", no it's not, it's pointing to exactly the same pace as 'pcw' is. And as as you call ->f(), BW::f() is the most direct f() implementation, so that's where it goes. Same story for 'pbw'. – Terence Simpson Feb 27 '11 at 13:11

1 Answers1

0

First of all, what you are doing is diamond inheritance and is usually a bad idea (some even say evil).

Now, names are displayed in their mangled format : you can use c++filt to demangle.

E.g : BW::_ZTv0_n12_N2BW1fEv means BW::virtual thunk to BW::f()

=> this might help you understand

Now, about your example pawpoints to a CW class. paw->f()

will call CW::f, whatever the way your cast it with a compatible class(that's the purpose of virtual stuff to implement interfaces).

Hope this helped, can't give more information currently.

Bruce
  • 7,094
  • 1
  • 25
  • 42