Can one extend virtual interface without recompilation of client code?
Asked Answered
P

1

8

A library provides a class with virtual functions. Can this class be extended with new virtual functions without recompiling binaries dynamically linked to the library?

I beleive this is not possible in standard. Are there platforms allowing this?

Would that be easier if new functions are only added to the end of the class body?

Pronuba answered 19/4, 2011 at 8:36 Comment(2)
I want to extend library interface. If there is another way to achieve this without changing signatures of API functions accepting main library class as argument, I'd love to know that too.Pronuba
there's an interesting document from the KDE project: Binary Compatibility Issues With C++. Links to two other docs you might be interested in reading.Bombardon
I
5

The standard is not concerned with binary compatibility. It is concerned though with classes, and by "changing" the definition of a class from one translation unit to another you indeed invoke undefined behavior.

Most compilers do allow a number of changes without the need for recompilation, however the list is small... and for this one I would say that it might not be possible, depending on the a priori knowledge of the derived classes.

The problem I foresee lies with the optimization that compilers usually carry out on the virtual tables.

When you create a class with virtual functions, you get a virtual table that looks like so:

// B virtual table
0 - Offset to complete object
1 - RTTI
2 - func0
3 - func1
...

In order to gain some space, the derived class own virtual functions are usually "appended":

// D virtual table
Same as B
N+3 - func(N+1)
N+4 - func(N+2)

This way a D object only has one virtual pointer, than can be used as such even when the type is (statically) a B (through pointer or reference).

However, if you were to extend B without recompiling D, then it would just plain crash, since when calling the N+1 function of B you would instead call the N+1 function of D which would probably not even have the same arguments... oups!

It can be done, though, if you know than no derived class add any virtual function of its own.

Inspan answered 19/4, 2011 at 8:52 Comment(4)
Note that some libraries add a couple of dummy virtual functions at the end (usually called reserved1, reserved2 etc.) so they can later be replaced without breaking binary compatibility.Erlindaerline
@Jan Hudec: clever :) Makes me think of spare bits ^^Inspan
As you say, the C++ standard does not include ABI compatibility. In fact it also does not mandate the use of a vtable for dynamic dispatching. It's just an implementation detail that most (all?) compilers happen to use.Karyogamy
@Cwan: by the way, if you know of papers about other implementations I would be extremely interested :)Inspan

© 2022 - 2024 — McMap. All rights reserved.