g++ undefined reference to typeinfo
Solution 1
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).
Solution 2
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]
Solution 3
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;
Solution 4
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.
Solution 5
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.
Related videos on Youtube
cdleary
Updated on September 03, 2021Comments
-
cdleary over 2 years
I just ran across the following error (and found the solution online, but it's not present in Stack Overflow):
(.gnu.linkonce.[stuff]): undefined reference to [method] [object file]:(.gnu.linkonce.[stuff]): undefined reference to `typeinfo for [classname]'
Why might one get one of these "undefined reference to typeinfo" linker errors?
(Bonus points if you can explain what's going on behind the scenes.)
-
Nav over 13 yearsI know it's an old post, but I had the same problem today, and the solution was simply to define my virtual function as virtual abc() {} in the base class, instead of virtual abc(); which gave the error.
-
dhardy almost 12 yearsbetter yet as
virtual void abc() =0;
(if the base version is never called) -
HelloGoodbye over 11 years@Nav: If you define
abc()
like that you can easily forget to redefineabc()
in the derived class and think that everything is okay, since you will still can call the function without any problem. A good practice for implementing pure virtual functions is found in this article, and this is to make the function print "Pure virtual function called" and then crash the program. -
Oleg Vazhnev over 9 yearsi was having same error. i've found that changing order of references to "lib" may help. i just moved problem lib's from the beggining to the end of the list and this resolved the problem
-
dwanderson about 8 yearsGAH. This is now at least the second time I've navigated exactly to this page, to read the comment by @dhardy and say to myself 'Doh'. Just spent 45minutes trying to track down some crazy behavior and all I needed was
= 0;
. -
Raghav Navada about 7 yearsIn my case, I changed the base destructor from = 0; to {};. Then it was fine. If you make a destructor virtual, you still have to define it in the base class. Because the derived class class destructor calls the base class destructor during destruction. It was unable to find the definition.
-
-
Alastair over 15 yearsUpmodded because I think this is more likely to be the cause of that specific error message (as opposed to the more general case of undefined methods...)
-
paxdiablo over 15 yearsOne thing I had to get used to with SO is not referring to "above" answers since the order may change based on votes. I don't usually refer to any other answers now since they can be deleted as well. My belief is that answers should be standalone. I still refer to user names for attribution however.
-
CesarB over 15 yearsYou can use typeid without a vtable; see my answer for the quotes from the gcc manual.
-
AnT stands with Russia almost 14 yearsIt is incorrect to say that
virtual void fn() = 0
is a definition. It is not a definition, but a mere declaration. The only reason the linker is not trying to resolve it is that the corresponding VMT entry will not refer to a function body (will contain null-pointer most likely). However, nobody prohibits you from calling this pure virtual function in a non-virtual manner, i.e. by using a fully-qualified name. In this case the linker will look for the body, and you will have to define the function. And yes, you can define a body for a pure virtual function. -
Chris Huang-Leaver over 13 yearsYou don't need to export (unhide) the base class if it is abstract or unused, just the non-virtual functions, normally just the constructor. The derived classes on the other hand have to be exported, if they are used.
-
Tatiana Racheva almost 13 yearsIn my case, I had a base class which declared but did not define virtual methods that were not pure virtual. Once I made them pure virtual, which is what I meant, the linker errors went away.
-
steipete almost 13 yearsTHANK YOU SO MUCH. That fixed my problem after 5 hour searching.
-
Sergiy Belozorov over 12 years@steipete: glad this is helpful :)
-
math about 12 yearssource link is dead, it was surely the same as permalink.gmane.org/gmane.comp.gcc.help/32475
-
Sergiy Belozorov about 12 yearsThanks for pointing this out. Original page is still available here: web.archive.org/web/20100503172629/http://www.pubbs.net/201004/…
-
Nawar about 11 yearsAnd sometimes one even must declare a body for a pure virtual function.
-
chmike almost 11 yearsThe compiler (g++) will tell you what is the missing symbol. Note: In case of dynamic library linking you may get a mangled name. Use c++filt <mangledNameVariable> to get it in a readable form. The typeinfo error with a class name was in my case because of a missing virtual destructor implementation in some base class.
-
spartygw over 10 yearsStackOverflow.com to the rescue again! I wish I could upvote more than once. After banging my head on the keyboard for an hour your answer was what I needed.
-
Admin almost 10 yearsThe question specifically mentions that it is typeinfo that is missing, which has to do with rtti. See comment from Damon in stackoverflow.com/questions/11904519/…
-
malat almost 10 yearsfeels like a hack, but it did solve the symptoms on my side. Thanks !
-
gbmhunter over 9 yearsI got this error because
-fno-rtti
was specified as a compiler option, not because a virtual function wasn't defined. I think it's a little misleading that the intro statement to this answer is "This particular error is caused by..." when it should rather be "One possible reason is because...". -
paxdiablo over 9 years@gbmhunter, fair enough. Made the change.
-
rholmes almost 9 years@TatianaRacheva Thanks! The error reporting from the linker is less than helpful and for a large interface it's very easy to miss the lack of the '=0;' for pure virtual!
-
Gabriel over 8 yearsn+1 lives saved and still counting :)
-
uwydoc about 8 yearspal, you saved me from one frustrating night. thanks a lot! in my case, i managed to workaround it by just moving the constructor implementation of my subclass to a separate file and apply '-fno-rtti' flag to that file. see my anwser for details
-
marsh almost 8 yearsThis was it for me, linking to a library with different RTTI settings.
-
Irene over 7 yearsThank you!!! I have spent over a day trying to find out why I was getting this error and nothing worked until I saw this reply and the one you linked to. Thanks so much!!
-
nnrales about 6 yearsI was only able to solve this error, when I set the virtual void fun() = 0. I missed the =0.
-
Guy Avraham over 5 years@paxdiablo - Perhaps it is a naive question, yet I was wondering: In Visual Studio (my case 15) this error does not rises (i.e.- the code compiles and runs correctly EVEN if I "
declare it without defining it in the same compilation unit
", meaning, the body of the virtual dtor is in the cpp file) - so, is it true to say that this is a "bug" in g++ (which does not happen in Visual Studio)? -
jaques-sam almost 5 yearsI have the same issue, but the target which fails has NOTHING to do with the target I applied
-frtti
for. How do you explain that?? There is only 1 connection, that it is that a header file which uses dynamic_cast is within the same used library... -
PieterNuyts over 4 yearsIn my case it was as simple as having forgotten the
= 0
after what I intended to be a pure virtual function definition (which is indeed interpreted by the compiler as "declaring a virtual function without defining it"). -
Fedor almost 3 yearsActually linking order matters with
clang
as well, so this advice is universally applicable, thanks. -
mostafa.elhoushi about 2 yearsThanks. I got this error when one library was compiled with
fno-rtti
while another wasn't. Ensuring that all libraries were built withfno-rtti
fixed the problem -
Daemon42 about 2 yearsYes fixing the link order ultimately resolved this for me. The undefined reference to typeinfo error referred to a non-virtual class used within a linked class, with error of the form somelibrary.a (somefile.o):(.gcc_except_table+0x23c): undefined reference to `typeinfo for NS:CLASSNAME' In this case NS:CLASSNAME was implemented in a library otherlib.a which needed to be moved below somelibrary.a in the link order. I had several other library order related errors, but this was the only one that manifested itself with the typeinfo error.