Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are C++ vtable methods ordered *In Practice*

Tags:

c++

vtable

In theory, C++ does not have a binary interface, and the order of methods in the vtable is undefined. Change anything about a class's definition and you need to recompile every class that depends upon it, in every dll etc.

But what I would like to know is how the compilers work in practice. I would hope that they just use the order that the methods are defined in the header/class, which would make appending additional methods safe. But they could also use a hash of the mangled names to make them order independent, but also then completely non-upgradable.

If people have specific knowledge of how specific versions of specific compilers work in different operating systems etc. then that would be most helpful.

Added: Ideally linker symbols would be created for the virtual methods offsets, so that the offsets would never be hard compiled into calling functions. But my understanding is that that is never done. Correct?

like image 210
Tuntable Avatar asked May 13 '15 05:05

Tuntable


3 Answers

It appears that of Microsoft the VTable may be reordered.

The following is copied from https://marc.info/?l=kde-core-devel&m=139744177410091&w=2

I (Nicolas Alvarez) can confirm this behavior happens.

I compiled this class:

struct Testobj {
    virtual void func1();
    virtual void func2();
    virtual void func3();
};

And a program that calls func1(); func2(); func3();

Then I added a func2(int) overload to the end:

struct Testobj {
    virtual void func1();
    virtual void func2();
    virtual void func3();
    virtual void func2(int);
};

and recompiled the class but not the program using the class.

Output of calling func1(); func2(); func3(); was

This is func1
This is func2 taking int
This is func2

This shows that if I declare func1() func2() func3() func2(int), the vtable is laid out as func1() func2(int) func2() func3().

Tested with MSVC2010.

like image 71
Tuntable Avatar answered Sep 17 '22 08:09

Tuntable


In MSVC 2010 they are in the order you declare them. I can't think of any rationale for another compiler doing it differently although it is an arbitrary choice. It only needs to be consistent. They are just arrays of pointers so don't worry about hashes or mangling.

No matter the order, additional virtual functions added in derived classes must come after those in the base or polymorphic casts would not work.

like image 44
tukra Avatar answered Sep 18 '22 08:09

tukra


As far as I know they are always in the order of declarations. This way you can always add declarations of new virtual methods at the end (or below all previous declaration of virtual methods). If you remove any virtual method or add new one somewhere in the middle - you do need to recompile and relink everything. I know that for sure - I already made that mistake. From my experience these rules apply to both MSVC and GCC.

like image 37
sirgeorge Avatar answered Sep 19 '22 08:09

sirgeorge