Undefined reference to `vtable for MyClass'



  • Hallo zusammen,

    erstmal ein frohes neues Jahr!

    Ich habe heute ein wenig meine CMakeLists.txts umsortiert (ich bin sicher, da müsste eingentlich mal ein Experte ran!) und plötzlich gab es beim Linken den Fehler

    In function `MyClass::MyClass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    Undefined reference to `vtable for MyClass'
    

    Natürlich habe ich schon etwas herumgegooglet und herausgefunden, dass das passieren soll, wenn der virtuelle Destruktor nicht implementiert ist.

    Ich habe aber virtual ~MyClass() = default; im Header.

    Dann habe das = default aus dem Header entfernt und MyClass::~MyClass() {} der .cpp-Datei hinzugefügt - und schwupps, es linkt wieder. Wie kann das sein?

    Ich kompiliere mit gcc version 7.4.0. Dann habe ich es mal mit clang version 7.1.0 versucht - und da kompiliert&linkt auch die Version mit = default im Header.

    Ist das ein Bug in gcc oder kann es irgendeine andere Ursache geben, die zu diesem Problem führt?



  • Das scheint ja eine ganz spezielle Implementierung der vtables des gcc zu sein. Gibt es keine andere virtuelle Funktion in der Klasse?

    Die Version 7.4 ist ja auch nicht mehr ganz frisch ...


  • Mod

    = default heisst nicht zwangsläufig, dass eine Definition fuer dich fabriziert wird. Schau mal hier, ob einer der Ausnahmefälle hier zutrifft: http://eel.is/c++draft/class#dtor-7

    Abgesehen davon wäre es hilfreich, wenn Du das Problem auf ein minimales Beispiel reduzierst und dieses postest, damit wir überhaupt etwas tangibles haben worüber wir sprechen. So hätten wir das ganze in 10 Sekunden auf einer Compiler-Website posten und kompilieren können.


  • Mod

    @manni66 C++11 war in der 4-er Reihe von GCC bereits abgehakt. Was da Version 7.4, die vor einem Jahr raus kam, im Bezug auf ein so banales Feature nicht können soll, verstehe ich nicht.



  • @Columbo sagte in Undefined reference to &#x60;vtable for MyClass':

    @manni66 C++11 war in der 4-er Reihe von GCC bereits abgehakt. Was da Version 7.4, die vor einem Jahr raus kam, im Bezug auf ein so banales Feature nicht können soll, verstehe ich nicht.

    Das dürfte wohl der selbe Effekt sein wie hier. Das könnte in neueren Versionen anders ausfallen.



  • @manni66 sagte in Undefined reference to &#x60;vtable for MyClass':

    Das scheint ja eine ganz spezielle Implementierung der vtables des gcc zu sein. Gibt es keine andere virtuelle Funktion in der Klasse?

    Keine von mir selbst geschriebene. Die Klasse muss aber virtuell sein, weil ROOT das für IO-Klassen so verlangt.

    Die Version 7.4 ist ja auch nicht mehr ganz frisch ...

    Ist halt, was bei Ubuntu 18 LTS dabei ist.

    @Columbo sagte in Undefined reference to &#x60;vtable for MyClass':

    = default heisst nicht zwangsläufig, dass eine Definition fuer dich fabriziert wird. Schau mal hier, ob einer der Ausnahmefälle hier zutrifft: http://eel.is/c++draft/class#dtor-7

    Hm. Spannend. Wenn ich das richtig verstehe, trifft keiner davon zu.

    Abgesehen davon wäre es hilfreich, wenn Du das Problem auf ein minimales Beispiel reduzierst und dieses postest, damit wir überhaupt etwas tangibles haben worüber wir sprechen. So hätten wir das ganze in 10 Sekunden auf einer Compiler-Website posten und kompilieren können.

    Tja, das ist ein Problem. Gengenommen handelt es sich um eine Klasse, die mittels ROOT IO durchführt. Daher hat diese Klasse bei mir ein paar POD-Data-Member und ein paar lesende und schreibende Funktionen, aber nichts mit "virtual". Allerdings will ROOT, dass die Klasse virtual ist. Daher würde es wohl nur helfen, wenn hier jemand auch ROOT nutzen würde und sich mit Dictionaries auskennt. Offenbar hängt es auch noch von meinem CMakeLists und dem wie ich es in eine .so kompiliere ab, da es zuvor noch mit demselben gcc kompilierte. Aber ich verstehe den Wunsch nach einem Minimalbeispiel natürlich. Ist nur nicht trivial zu erstellen...

    PS: Danke @manni66 für den Link. Tja, dann geht wohl doch ein total simples Minimalbeispiel. Ich verstehe nur nicht, warum es durch ein paar CMakeLists-Änderungen aufgetreten ist. Aber CMake ist ein Buch mit 13 Siegeln für mich 🙂



  • @manni66 sagte in Undefined reference to &#x60;vtable for MyClass':

    Das dürfte wohl der selbe Effekt sein wie hier. Das könnte in neueren Versionen anders ausfallen.

    @wob Da würde mich echt mal interessieren, ob das dann tatsächlich mit = default im Header funktioniert, wenn man stattdessen eine andere, nicht-virtuelle Memberfunktion der Klasse in die .cpp packt.

    Btw... man kann default auch bei der Definition in der .cpp verwenden: MyClass::~MyClass() = default; ... die Member-Funktion ist dann nicht implizit inline.



  • Das hilft keinem weiter, aber mir kommt sowas vage bekannt vor... Hatte sowas auch schon irgendwann letztes Jahr. Allerdings mit qmake und VS.
    Ich kann mich jetzt nicht mehr genauer dran erinnern, aber ich glaube, bei mir war das Problem, dass irgendwelche Defines verlorengegangen waren, für das declspec import/export Zeug.


Anmelden zum Antworten