Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the first (int (*)(...))0 vtable entry in the output of g++ -fdump-class-hierarchy?

For this code:

class B1{ public:     virtual void f1() {}   };  class D : public B1 { public:   void f1() {} };  int main () {     B1 *b1 = new B1();     D  *d  = new D();      return 0; } 

After compilation, the vtable I get with g++ -fdump-class-hierarchy is:

Vtable for B1 B1::_ZTV2B1: 3u entries 0     (int (*)(...))0 8     (int (*)(...))(& _ZTI2B1) 16    B1::f1   Vtable for D D::_ZTV1D: 3u entries 0     (int (*)(...))0 8     (int (*)(...))(& _ZTI1D) 16    D::f1 

I failed to understand what do the entries like (int ()(...))0* correspond to. Of course it means something like, it is a function which returns an int and takes unlimited number of arguments, I don't understand anything further. To which function does this function pointer correspond to? and how do you know that? Mine is a 64 bit machine.

The second function pointer has an address associated at end?? To whom does that correspond to?

EDIT

The compiler, I use is g++:

g++ -v Using built-in specs. Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.4 --enable-linux-futex --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux Thread model: posix *gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux)* 
like image 732
Aquarius_Girl Avatar asked Apr 19 '11 07:04

Aquarius_Girl


People also ask

What is vtable and memory allocation in vtable?

Vtable is like an array of function pointer. Vtable and Vptr is creating at compile time which will get memory in run time and vtable entries are virtual function addresses . Every object of a class containing a virtual function will have an extra pointer which is pointing to Virtual Table is known as virtual pointer.

What is use of vtable in in inheritance?

You can imagine what happens when you perform inheritance and override some of the virtual functions. The compiler creates a new VTABLE for your new class, and it inserts your new function addresses using the base-class function addresses for any virtual functions you don't override.

What is a vtable in C++?

The virtual table is a lookup table of functions used to resolve function calls in a dynamic/late binding manner. The virtual table sometimes goes by other names, such as “vtable”, “virtual function table”, “virtual method table”, or “dispatch table”.

What is VPTR and vtable in C++?

The compiler places the addresses of the virtual functions for that particular class in the VTABLE. In each class with virtual functions, it secretly places a pointer, called the vpointer (abbreviated as VPTR), which points to the VTABLE for that object.


1 Answers

Those are the offset-to-top (needed for multiple inheritence) and typeinfo (RTTI) pointers.

From the Itanium ABI (you are not using the Itanium compiler, but their description of this is really good):

The offset to top holds the displacement to the top of the object from the location within the object of the virtual table pointer that addresses this virtual table, as a ptrdiff_t. It is always present. The offset provides a way to find the top of the object from any base subobject with a virtual table pointer. This is necessary for dynamic_cast in particular.
(In a complete object virtual table, and therefore in all of its primary base virtual tables, the value of this offset will be zero. [...])

The typeinfo pointer points to the typeinfo object used for RTTI. It is always present. All entries in each of the virtual tables for a given class must point to the same typeinfo object. A correct implementation of typeinfo equality is to check pointer equality, except for pointers (directly or indirectly) to incomplete types. The typeinfo pointer is a valid pointer for polymorphic classes, i.e. those with virtual functions, and is zero for non-polymorphic classes.


Offset-to-top in more detail (by request)

Let's say you have a derived class D that derives from a base class, B1. What happens when you try to cast a D instance to type B1? Since functions that take a B1 object don't know anything about D, part of the D vtable must also be a valid B1 vtable. This is easy enough - just make the start of the D vtable look like a B1 vtable, and add on any additional entries we need after that. Functions expecting a B1 will be happy, because they won't use any part of the vtable beyond what they're expecting for a B1.

However, what happens if D now also derives from B2? The pointer to the D vtable can't be both a valid B1 vtable and a valid B2 vtable! The compiler solves this by appending a separate B2 vtable to the end of our combined D/B1 vtable, and adjusts the vtable-pointer manually when we try to cast from a D to a B2.

However, this leads to a new problem - what happens when we try to cast back from a B2 to a D? The compiler can't just adjust the vtable-pointer backwards by the same amount it adjusted the pointer previously, because it doesn't actually know for sure that the B2 object we're giving it is of type D! In particular, dynamic_cast<D>() must be able to tell if our object is or isn't of type D. For that, it needs to access the object's RTTI, and for that, it needs to know where the start of the original object's vtable is. This is the purpose of the offset-to-top value - it gives us the offset to the start of the original object's vtable, we get our object's RTTI, and the vengeful god of C++ allows our crops to grow for another season.

This page has some good examples of vtable layouts (under Table 1c). Note that they are slightly more complicated due to the use of virtual inheritance, which adds an extra offset to the vtable of each child class.

like image 176
BlueRaja - Danny Pflughoeft Avatar answered Oct 11 '22 08:10

BlueRaja - Danny Pflughoeft