I have the following MWE:
// classes.hpp
#pragma once
struct Base {
    virtual ~Base() = default;
    virtual void tell() = 0;
};
struct Derived : Base {
    Derived() = default;
    ~Derived() = default;
    void tell() override;
};
then,
// classes.cpp
#include <iostream>
#include "classes.hpp"
extern "C" {
Derived* instantiate()
{
    return new Derived{};
}
void deinstantiate(Derived* ptr)
{
    delete ptr;
}
}
void Derived::tell()
{
    std::cout << "Hello!" << std::endl;
}
which I compile on a linux machine as a shared library g++ -fPIC -shared -o classes.so classes.cpp and the main program:
// main.cpp
#include <iostream>
#include <dlfcn.h>
#include "classes.hpp"
int main()
{
    using inst_t = Derived*(*)(void);
    using deinst_t = void(*)(Derived*);
    void* handle = dlopen("./classes.so", RTLD_NOW);
    inst_t inst = reinterpret_cast<inst_t>(dlsym(handle, "instantiate"));
    deinst_t deinst = reinterpret_cast<deinst_t>(dlsym(handle, "deinstantiate"));
    // some tests here...
    Derived* instance = inst();
    instance->tell();
    deinst(instance);
    dlclose(handle);
    return EXIT_SUCCESS;
}
which I compile with g++ -ldl -o main main.cpp
It works well. However If I remove the inheritance of Derived from Base, i.e. if I substitute above calsses.hpp file with
// new classes.hpp
#pragma once
struct Derived {
    Derived() = default;
    ~Derived() = default;
    void tell();
};
I got a link error
/usr/bin/ld: /tmp/ccLuFAZr.o: in function `main':
main.cpp:(.text+0x66): undefined reference to `Derived::tell()'
collect2: error: ld returned 1 exit status
which I is sensible since it cannot find the symbol from classes.cpp.
However it is not completely clear to me how subclassing Derived from Base can solve this problem since Base is not used at all. (I think it should be a matter o vtable creation). So
- How is it possible?
- Is there any other way to solve the problem without using (dummy) inheritance?
EDIT
Of course the cause of a linking error can be found in a question whose answers list all the possible cause of linking errors. However, in my opinion this question is by far more generic than mine which deals with a particular situation (the use of dynamic shared library, ecc).
EDIT 2
Non-question: Why, without inheritance, do I get link error? (I know)
Question: Why using inheritance do I not get link error?
 
     
    