Felix
Felix

Reputation: 7146

C++ Inheritance and dynamic libraries

The idea is the following. I have a library Version 1 with a class that looks as follows:

class MY_EXPORT MyClass
{
public:
    virtual void myMethod(int p1);
}

In Version 2, the class was modified to this:

class MY_EXPORT MyClass
{
public:
    virtual void myMethod(int p1);
    virtual void myMethod2(int p1, int p2);
}

//implementation of myMethod2 in cpp file
void MyClass::myMethod2(int p1, int p2)
{
    myMethod(p1);
    //...
}

Now imagine a user compiled againts Version 1 of the library, and extended MyClass by overriding myMethod. Now he updates the library to version 2, without recompiling. Let's further assume the dynamic linker still successfully finds the library and loads it.

The question is, if I call the method instance->myMethod2(1, 2); somwhere inside the library, will it work, or will the application crash? In both cases, the class has no members and thus is of the same size.

Upvotes: 2

Views: 932

Answers (3)

Mark Ransom
Mark Ransom

Reputation: 308206

By changing the definition of the class without recompiling, you've violated the One Definition Rule. The user who did not recompile is using the old definition, while your library is using the new definition. This results in undefined behavior.

To see how this might manifest, consider the typical implementation of virtual functions which uses a VTable to dispatch function calls. The library user has derived a class, and this derived class has only one function in the VTable. If a pointer or reference to this class is passed into the library, and the library tries to call the second function, it will attempt to access a VTable entry that doesn't exist. This will almost always result in a crash, although nothing is guaranteed when it comes to undefined behavior.

Upvotes: 0

yugr
yugr

Reputation: 21886

KDE C++ ABI guidelines specifically prohibit such change. Virtual tables of derived classes will not contain addresses for new methods and so virtual calls of those methods on objects of derived classes will crash.

Upvotes: 1

Pavel P
Pavel P

Reputation: 16843

I don't think there is point to guess if that app will crash or not, behavior is undefined. The application has to be recompiled, since there was ABI change in the library.

When library calls instance->myMethod2(1, 2); it will have to go through virtual table that was created in the application code with the assumption that there is only one virtual method: myMethod. From that point, you get undefined behavior. In short, you have to recompile you application when library ABI changes.

Upvotes: 3

Related Questions