Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a vtable contain duplicate functions?

Imagine a project in which there is an interface class like the following:

struct Interface
{
    virtual void f()=0;
    virtual void g()=0;
    virtual void h()=0;
};

Suppose that somewhere else, someone wishes to create a class implementing this interface, for which f, g, h all do the same thing.

struct S : Interface
{
    virtual void f() {}
    virtual void g() {f();}
    virtual void h() {f();}
};

Then it would be a valid optimisation to generate a vtable for S whose entries are all pointers to S::f, thus saving a call to the wrapping functions g and h.

Printing the contents of the vtable, however, shows that this optimisation is not performed:

S s;
void **vtable = *(void***)(&s);  /* I'm sorry. */
for (int i = 0; i < 3; i++)
    std::cout << vtable[i] << '\n';

0x400940
0x400950
0x400970

Compiling with -O3 or -Os has no effect, as does switching between clang and gcc.

Why is this optimisation opportunity missed?

At the moment, these are the guesses that I have considered (and rejected):

  1. The vtable printing code actually prints garbage.
  2. The performance improvement is considered worthless.
  3. The ABI prohibits it.
like image 667
PBS Avatar asked Sep 01 '15 18:09

PBS


People also ask

Does vtable contain non virtual functions?

No. A vtable only contains pointers to virtual functions in the same class or file.

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.

How does C++ vtable work?

For every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.

What is the purpose of vtable and VPTR 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

Such optimization is not valid because...

// somewhere-in-another-galaxy.hpp
struct X : S {
    virtual void f();
};

// somewhere-in-another-galaxy.cpp
include <iostream>
void X::f() {
    std::cout << "Hi from a galaxy far, far away! ";
}

If a compiler implements your optimization this code would not work.

Interface* object = new X;
object->g();

A compiler of my translation unit does not know about your class internal implementation so for g() and h() it just puts in my class' virtual functions table references to the corresponding entries in your class' VFT.

like image 127
Alan Milton Avatar answered Oct 06 '22 21:10

Alan Milton