-6

In regards to give a solution for this question, I tried to simplify my code presented in the answer to use RTTI and the typeid() function to retrieve a class name:

#include <iostream>
#include <string>
#include <typeinfo>

struct IDriver {
    // Public virtual API:
    virtual void func1() = 0;
    // ...
    virtual ~IDriver() {}
};

class SpecificDriver;

template<typename Derived>
class Driver : public IDriver {
public:
    Driver() {
         std::cout << typeid(*this).name() << std::endl;
         std::cout << typeid(Derived).name() << std::endl;
    }  
    virtual ~Driver() {}
};

class SpecificDriver : public Driver<SpecificDriver> {
public:
    // Public virtual API:
    virtual void func1();
    virtual ~SpecificDriver() {}
};

int main() {
    SpecificDriver sd;
}

Using this code results in a linker error:

/tmp/ccXnTrfe.o: In function `main':
main.cpp:(.text.startup+0x4f): undefined reference to `typeinfo for SpecificDriver'

Why does this result in an undefined reference error for the typeinfo rather than the missing func1() definition (where it's not even used BTW)?


Interestingly enough when I remove all the virtual stuff, it works just fine:

#include <iostream>
#include <string>
#include <typeinfo>

template<typename Derived>
class Driver {
public:
    Driver() {
         std::cout << typeid(*this).name() << std::endl;
         std::cout << typeid(Derived).name() << std::endl;
    }  
};

class SpecificDriver : public Driver<SpecificDriver> {
};

int main() {
    SpecificDriver sd;
}

Output:

6DriverI14SpecificDriverE
14SpecificDriver

Demo

So is this really related to vtable generation?

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190

2 Answers2

2

So why missed implementation of virtual void func1(); in SpecificDriver

// Public virtual API:
virtual void func1();

cause message about missed typeinfo?

The detailed answer can be found here:

http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf

or here http://www.avabodh.com/cxxin/virtualfunction.html

the short answer because for gcc and clang compiler implement rtti lookup for class with vtable via vtable.

In your case if you compile code without optimization, gcc give you:

undefined reference to `vtable for SpecificDriver'

undefined reference to `typeinfo for SpecificDriver'

coliru by default using -O2 optimization level, so it optimize code like this:

auto p1 = get_ptr_to_vtable();
auto p2 = get_ptr_to_typeinfo(p1);

to just

auto p2 = CONSTANT;

and give error only about missed typeinfo.

fghj
  • 8,898
  • 4
  • 28
  • 56
  • But why does the linker complain about `typeinfo`? Moreover `func1()` isn't even called anywhere. – πάντα ῥεῖ May 01 '16 at 10:54
  • vtable and info used by `typeid` is defined where you define the first declared virtual function. If you don't define it, you also don't define these. – milleniumbug May 01 '16 at 10:56
  • Indeed your answer [fixes that](http://coliru.stacked-crooked.com/a/fdbcdab81ae13c29), but I'm still confused about the linker error message. – πάντα ῥεῖ May 01 '16 at 10:57
  • probably it generates the rtti in the same unit as the vtable, and it never generated the vtable due to the missing body – M.M May 01 '16 at 10:57
  • 2
    Possibly because you're using gcc, and its [documentation](https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html) states that the type information is written out along with the vtable for a class (which is missing in your case) – nos May 01 '16 at 11:00
  • @πάνταῥεῖ simple way to deal with typeinfo information is put it into `vtable`, see http://www.avabodh.com/cxxin/virtualfunction.html – fghj May 01 '16 at 11:05
  • @nos That might well explain it. Though I've tried `c++` on coliru (not sure if it calls clang), and got the same result. – πάντα ῥεῖ May 01 '16 at 11:09
  • @nos Also, why it works fine when no vtable is involved? – πάντα ῥεῖ May 01 '16 at 11:30
  • @user1034749 Sorry, I've changed my question to clarify my concerns. So your answer has gone a bit out of scope. – πάντα ῥεῖ May 01 '16 at 12:39
  • @πάνταῥεῖ Because in that case the compiler writes chose to write out the type info whenever the type info is used, and not when the vtable is written. – nos May 01 '16 at 17:31
1

Basically this question is a duplicate of g++ undefined reference to typeinfo.

Note that according to the standard, the program is ill-formed, no diagnostic required, if not all the non-pure virtual functions are defined:

N4582 [basic.def.odr]p3

A virtual member function is odr-used if it is not pure.

N4582 [basic.def.odr]p4

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. [...] An inline function shall be defined in every translation unit in which it is odr-used.

Community
  • 1
  • 1
cpplearner
  • 13,776
  • 2
  • 47
  • 72