c++compilationlinkerabipimpl-idiom

C++ abi compatability without pimpl using abstract class


Suppose I have a class B_Impl which inherits and implements a pure abstract class B (not containing any data-fields).

Suppose class A uses B_Impl via B* only.

If I add a field to B_Impl.h (clearly, not included by A), will ABI compatability be preserved?

I thought, that it will not be preserved, -- after reading https://wiki.qt.io/D-Pointer.

But I can see in my app that after changing B_Impl.h, the object file for class A is not regenerated and everything still works great.

Maybe, this is because in my app A and B are part of the same app and B is not a library called by A? Or is it because vtable is located as the very first field in the memory always and adding another field to B_Impl.h (which is "beneath" B) does not change the fact that vtable is the first field? Or is this stuff somehow corrected by the linker rather than by re-generating A-object-file?

Honestly, I am a bit confused here:


Solution

  • If I add a field to B_Impl.h (clearly, not included by A), will ABI compatability be preserved?

    Yes. If a translation unit doesn't include the definition of B_Impl, then changes to B_Impl won't affect the compatibility.

    The interface compatibility - whether it is API or ABI - matters only when the interface is used. In your example, the interface of B is used; not the interface of B_Impl.

    Is this ABI problem is only about libraries?

    Whether B_Impl is in a library or not shouldn't matter.