2

I was trying to learn the implementation of V-table in C++. I used -fdump-class-hierarchy option with g++ to get an idea what a virtual table would look like. Got to understand the concept of 'offset to top', 'RTTI', virtual function, etc in the v-table. Then, I tried the same by deriving my class virtually and could see many entries added.

Code:

class Base
{
   public:
      virtual void print() { cout << "Base Print" << endl; }
};

class Derived1 : public Base
{
   public:
      virtual void print() { cout << "Derived1 Print" << endl; }
};

This gives the following vtable:

Vtable for Base
Base::_ZTV4Base: 3u entries
0     0u
4     (int (*)(...))(&_ZTI4Base)
8     Base::print

Class Base
   size=4 align=4
   base size=4 base align=4
Base (0xb6f51480) 0 nearly-empty
    vptr=((&Base::_ZTV4Base) + 8u)

Vtable for Derived1
Derived1::_ZTV8Derived1: 3u entries
0     0u
4     (int (*)(...))(&_ZTI8Derived1)
8     Derived1::print

Class Derived1
   size=4 align=4
   base size=4 base align=4
Derived1 (0xb6f51980) 0 nearly-empty
    vptr=((&Derived1::_ZTV8Derived1) + 8u)
  Base (0xb6f519c0) 0 nearly-empty
      primary-for Derived1 (0xb6f51980)

Now, if I derive virtual'ly using

class Derived1 : public virtual Base

I get the following

Vtable for Base
Base::_ZTV4Base: 3u entries
0     0u                           <----- Offset to top pointer
4     (int (*)(...))(&_ZTI4Base)   <----- RTTI Pointer
8     Base::print                  <----- Virtual Function

Class Base
   size=4 align=4
   base size=4 base align=4
Base (0xb6f51480) 0 nearly-empty
    vptr=((&Base::_ZTV4Base) + 8u)  <----- This takes to Base::print ?

Vtable for Derived1
Derived1::_ZTV8Derived1: 5u entries
0     0u   <---- Which of these 2 is virtual base offset and what is other one?
4     0u    
8     0u    <---- offset to top for Derived1
12    (int (*)(...))(&_ZTI8Derived1)  <----- RTTI Pointer
16    Derived1::print                 <----- Virtual Function

VTT for Derived1
Derived1::_ZTT8Derived1: 2u entries
0     (const void*)((void*)((&Derived1::_ZTV8Derived1) + 16u)) <--- Why 2 same entries here ?
4     (const void*)((void*)((&Derived1::_ZTV8Derived1) + 16u))

Class Derived1
   size=4 align=4
   base size=4 base align=4
Derived1 (0xb6f51980) 0 nearly-empty
    vptridx=0u vptr=((&Derived1::_ZTV8Derived1) + 16u) <----- This takes to Derived1::print ?
  Base (0xb6f519c0) 0 nearly-empty virtual
      primary-for Derived1 (0xb6f51980)
      vptridx=4u vbaseoffset=-0x000000010

Questions:

  • Why are there extra entries for offsets (0u) ?
  • What is the purpose of "VTT" section what does it contain?
  • What is vptridx ?

I went through various links on SO and outside, but could not get a complete explanation.

Thanks for the responses in advance.

EDIT: Thanks very much for the link (duplicate). I have added my understanding in the comments above. But there are still some questions? Can anyone help?

user2255299
  • 185
  • 7

0 Answers0