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?