Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ undefined reference to typeinfo

Tags:

c++

g++

linker

One possible reason is because you are declaring a virtual function without defining it.

When you declare it without defining it in the same compilation unit, you're indicating that it's defined somewhere else - this means the linker phase will try to find it in one of the other compilation units (or libraries).

An example of defining the virtual function is:

virtual void fn() { /* insert code here */ }

In this case, you are attaching a definition to the declaration, which means the linker doesn't need to resolve it later.

The line

virtual void fn();

declares fn() without defining it and will cause the error message you asked about.

It's very similar to the code:

extern int i;
int *pi = &i;

which states that the integer i is declared in another compilation unit which must be resolved at link time (otherwise pi can't be set to it's address).


This can also happen when you mix -fno-rtti and -frtti code. Then you need to ensure that any class, which type_info is accessed in the -frtti code, have their key method compiled with -frtti. Such access can happen when you create an object of the class, use dynamic_cast etc.

[source]


This occurs when declared (non-pure) virtual functions are missing bodies. In your class definition, something like:

virtual void foo();

Should be defined (inline or in a linked source file):

virtual void foo() {}

Or declared pure virtual:

virtual void foo() = 0;

Quoting from the gcc manual:

For polymorphic classes (classes with virtual functions), the type_info object is written out along with the vtable [...] For all other types, we write out the type_info object when it is used: when applying `typeid' to an expression, throwing an object, or referring to a type in a catch clause or exception specification.

And a bit earlier on the same page:

If the class declares any non-inline, non-pure virtual functions, the first one is chosen as the “key method” for the class, and the vtable is only emitted in the translation unit where the key method is defined.

So, this error happens when the "key method" is missing its definition, as other answers already mentioned.


If you're linking one .so to another, yet one more possibility is compiling with "-fvisibility=hidden" in gcc or g++. If both .so files were built with "-fvisibility=hidden" and the key method is not in the same .so as another of the virtual function's implementations, the latter won't see the vtable or typeinfo of the former. To the linker, this looks like an unimplemented virtual function (as in paxdiablo's and cdleary's answers).

In this case, you must make an exception for the visibility of the base class with

__attribute__ ((visibility("default")))

in the class declaration. For instance,

class __attribute__ ((visibility("default"))) boom{
    virtual void stick();
}

Another solution, of course, is to not use "-fvisibility=hidden." That does complicate things for the compiler and linker, possibly to the detriment of code performance.


The previous answers are correct, but this error can also be caused by attempting to use typeid on an object of a class that has no virtual functions. C++ RTTI requires a vtable, so classes that you wish to perform type identification on require at least one virtual function.

If you want type information to work on a class for which you don't really want any virtual functions, make the destructor virtual.


I just spent a few hours on this error, and while the other answers here helped me understand what was going on, they did not fix my particular problem.

I am working on a project that compiles using both clang++ and g++. I was having no linking issues using clang++, but was getting the undefined reference to 'typeinfo for error with g++.

The important point: Linking order MATTERS with g++. If you list the libraries you want to link in an order which is incorrect you can get the typeinfo error.

See this SO question for more details on linking order with gcc/g++.