8

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?

Tuntable
  • 3,276
  • 1
  • 21
  • 26
  • I would have to check to make sure I'm pretty sure they are in the order you declare them. If you derive a sub class and add more virtual functions they certainly come after the base class functions. – tukra May 13 '15 at 05:21
  • Not only the order of the methods in the vtable, but also the existence of the vtable is an implementation detail. The standard only specify the virtual functions not their implentation :-) – Serge Ballesta May 13 '15 at 06:07

4 Answers4

3

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.

Tuntable
  • 3,276
  • 1
  • 21
  • 26
2

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.

tukra
  • 921
  • 8
  • 13
1

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.

sirgeorge
  • 6,331
  • 1
  • 28
  • 33
0

Any compiler must at least place all the viable entries for a specific class together, with those for derived classes coming either before or afterwards, and also together.

The easiest way to accomplish that is to use the header order. It is difficult to see why any compiler would do anything different, given that it requires more code, more testing, etc., and just provides another way for mistakes to occur. No identifiable benefit that I can see.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Well, if the order of the methods was different in different headers for the same class then using a hash of a mangled name would fix that. The order that methods appear should not be relevant, according to the standard (I guess). Not that I think that is a good idea, but it is a rationale for using a different order. – Tuntable May 13 '15 at 06:16
  • 1
    'if the order of the methods was different in different headers for the same class' This violates the one definition rule. So the result is undefined behaviour! – Klaus May 13 '15 at 06:54