Search code examples
c++linkershared-librariespure-virtual

C++ shared library: Pure virtual function does not cause link error


I have been struggling to understand why I can create a pure virtual function in a header file that has not been implemented in the library I am using, and that this will not cause a link or even run-time failure.. The above might be a little imprecise, but here is some code to back it up.

Here is an interface definition:

class A
{
public:
    static A* Create();

    virtual ~A() {}

    virtual status_t start() = 0;
    virtual status_t stop() = 0;
};

I have a C++ shared library that contains an implementation "AImpl" + the A::Create() function (see below):

A* A::Create {return new AImpl;}

class AImpl : public A
{
public:
    A() {}
    virtual ~A() {}

    virtual status_t start() {}
    virtual status_t stop()  {}
};

I build the shared library - No problem. Now I add another pure virtual function in the header file for Class A:

class A
    {
    public:
        static A* Create();

        virtual ~A() {}

        virtual status_t start() = 0;
        virtual status_t stop() = 0;
        virtual status_t write() = 0;
    };

I create a test app that uses it:

void main()
{
    A* a = A::Create();
    a->start();
    a->stop();
    a->write();
}

Now I understand that the above compiles, but I would think that it would fail linking, since there is no implementation for the write() call in the shared library. Even at runtime, no crash or anything is happening. It just seems like the write call is skipped. Can anyone help explain - it would be greatly appreciated :-)

Thanks - And sorry for the lengthy question, it was a bit hard for me to explain the exact issue in a "single liner"..


Solution

  • What's going on is the shared library was built with one version of the A class while the executable binary was built with a different version. At this point you've violated the one definition rule and the compiler is free to do anything, including compiling and linking your code successfully. There is no requirement for compiler diagnostics in this situation.