Why might one get one of these "undefined reference to typeinfo" linker errors?
Can anyone explain what's going on behind the scenes?
I 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.
Commented Nov 30, 2010 at 9:04 better yet as virtual void abc() =0; (if the base version is never called) Commented Jul 9, 2012 at 8:27@Nav: If you define abc() like that you can easily forget to redefine abc() 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.
Commented Sep 27, 2012 at 11:44i 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
Commented Sep 23, 2014 at 10:02GAH. 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; .
Commented Mar 9, 2016 at 22:19One 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.
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).
answered Nov 21, 2008 at 0:42 875k 240 240 gold badges 1.6k 1.6k silver badges 2k 2k bronze badgesIt 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.
Commented Jun 25, 2010 at 0:41 And sometimes one even must declare a body for a pure virtual function. Commented Mar 25, 2013 at 1:31The 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
The 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/…
– user2088639 Commented May 9, 2014 at 22:38I 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. ".
Commented Sep 11, 2014 at 4:10This 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.
answered Nov 15, 2010 at 13:37 Sergiy Belozorov Sergiy Belozorov 5,994 7 7 gold badges 41 41 silver badges 74 74 bronze badges source link is dead, it was surely the same as permalink.gmane.org/gmane.comp.gcc.help/32475 Commented Apr 13, 2012 at 10:10Thanks for pointing this out. Original page is still available here: web.archive.org/web/20100503172629/http://www.pubbs.net/201004/…
Commented Apr 14, 2012 at 7:04pal, 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
Commented Mar 31, 2016 at 7:14I 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.
Commented May 29, 2019 at 13:50Thanks. I got this error when one library was compiled with fno-rtti while another wasn't. Ensuring that all libraries were built with fno-rtti fixed the problem
Commented Feb 7, 2022 at 5:50This 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;
answered Nov 21, 2008 at 0:17
71.1k 55 55 gold badges 164 164 silver badges 194 194 bronze badges
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.
answered Nov 21, 2008 at 1:34 45.2k 7 7 gold badges 64 64 silver badges 86 86 bronze badgesIn 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.
Commented Jun 16, 2011 at 18:42@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!
Commented May 15, 2015 at 19:11If 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
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.
answered Jun 25, 2010 at 0:24 281 3 3 silver badges 2 2 bronze badgesYou 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.
Commented Dec 20, 2010 at 18:36 feels like a hack, but it did solve the symptoms on my side. Thanks ! Commented Jul 28, 2014 at 7:19The 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.
31.5k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Nov 21, 2008 at 0:49 Tyler McHenry Tyler McHenry 76.2k 18 18 gold badges 123 123 silver badges 168 168 bronze badgesUpmodded 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. )
Commented Nov 21, 2008 at 1:20One 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.
Commented Nov 21, 2008 at 1:37 You can use typeid without a vtable; see my answer for the quotes from the gcc manual. Commented Nov 21, 2008 at 1:37I 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++ .
1 1 1 silver badge answered Dec 1, 2015 at 23:01 2,736 3 3 gold badges 28 28 silver badges 46 46 bronze badgesThank 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!!
Commented Dec 30, 2016 at 4:23 Actually linking order matters with clang as well, so this advice is universally applicable, thanks. Commented Jun 26, 2021 at 13:37Yes 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.
Commented Feb 9, 2022 at 1:16Possible solutions for code that deal with RTTI and non-RTTI libraries:
a) Recompile everything with either -frtti or -fno-rtti
b) If a) is not possible for you, try the following:
Assume libfoo is built without RTTI. Your code uses libfoo and compiles with RTTI. If you use a class (Foo) in libfoo that has virtuals, you're likely to run into a link-time error that says: missing typeinfo for class Foo.
Define another class (e.g. FooAdapter) that has no virtual and will forward calls to Foo that you use.
Compile FooAdapter in a small static library that doesn't use RTTI and only depends on libfoo symbols. Provide a header for it and use that instead in your code (which uses RTTI). Since FooAdapter has no virtual function it won't have any typeinfo and you'll be able to link your binary. If you use a lot of different classes from libfoo, this solution may not be convenient, but it's a start.
31.5k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Jun 11, 2011 at 1:35 121 1 1 silver badge 2 2 bronze badges This was it for me, linking to a library with different RTTI settings. Commented May 10, 2016 at 15:35In my case it was a virtual function in an interface class that wasn't defined as a pure virtual.
class IInterface
I forgot the = 0 bit.
answered Feb 27, 2020 at 14:32 Goosebumps Goosebumps 939 2 2 gold badges 14 14 silver badges 28 28 bronze badgesIn the base class (an abstract base class) you declare a virtual destructor and as you cannot declare a destructor as a pure virtual function, either you have to define it right here in the abstract class, just a dummy definition like virtual ~base() < >will do, or in any of the derived class.
If you fail to do this, you will end up in an "undefined symbol" at link time. Since VMT has an entry for all the pure virtual functions with a matching NULL as it updates the table depending on the implementation in the derived class. But for the non-pure but virtual functions, it needs the definition at the link time so that it can update the VMT table.
Use c++filt to demangle the symbol. Like $c++filt _ZTIN10storageapi8BaseHostE will output something like "typeinfo for storageapi::BaseHost".
31.5k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Apr 19, 2011 at 22:59 81 1 1 silver badge 1 1 bronze badgeSimilarly to the RTTI, NO-RTTI discussion above, this problem can also occur if you use dynamic_cast and fail to include the object code containing the class implementation.
I ran into this problem building on Cygwin and then porting code to Linux. The make files, directory structure and even the gcc versions (4.8.2) were identical in both cases, but the code linked and operated correctly on Cygwin but failed to link on Linux. Red Hat Cygwin has apparently made compiler/linker modifications that avoid the object code linking requirement.
The Linux linker error message properly directed me to the dynamic_cast line, but earlier messages in this forum had me looking for missing function implementations rather than the actual problem: missing object code. My workaround was to substitute a virtual type function in the base and derived class, e.g. virtual int isSpecialType(), rather than use dynamic_cast. This technique avoids the requirement to link object implementation code just to get dynamic_cast to work properly.
answered May 13, 2014 at 20:15 321 2 2 silver badges 9 9 bronze badgesI've got same error when my interface (with all pure virtual functions) needed one more function and I forgot to "null" it.
Last vaClose is not virtual so compiled did not know where to get implementation for it and thereby got confused. my message was:
. TCPClient.o:(.rodata+0x38): undefined reference to `typeinfo for ICommProvider'
Simple change from
virtual int vaClose();
virtual int vaClose() = 0;
fixed the problem. hope it helps
answered Aug 25, 2016 at 22:06 Alex Paniutin Alex Paniutin 144 1 1 silver badge 2 2 bronze badgesI got a lot of these errors just now. What happened is that I split a header-file-only class into a header file and a cpp file. However, I didn't update my build system, so the cpp file didn't get compiled. Among simply having undefined references to the functions declared in the header but not implemented, I got a lot of these typeinfo errors.
The solution was to re-run the build system to compile and link the new cpp file.
answered Dec 15, 2014 at 23:56 228k 169 169 gold badges 500 500 silver badges 694 694 bronze badgesin my case, i used a third-party library with header files and so file. i subclassed one class, and link error like this occurred when i try to instantiate my subclass.
as mentioned by @sergiy, knowning it could be the problem of 'rtti', i managed to workaround it by put the constructor implementation into separate .cpp file and apply '-fno-rtti' compile flags to the file. it works well.
as i am still not quite clear about the internal of this link error, i am not sure whether my solution is general. however, i think it worth a shot before trying the adaptor way as mentioned by @francois . and of course, if all source codes are available(not in my case), better do recompile with '-frtti' if possible.
one more thing, if you choose to try my solution, try make the separate file as simple as possible, and do not use some fancy features of C++. take special attention on boost related things, cause much of it depends on rtti.
answered Mar 31, 2016 at 7:08 83 1 1 gold badge 1 1 silver badge 8 8 bronze badgesWith this error message, G++'s linker is telling you, that it cannot assemble the full static typeinfo descriptor for a given class, when it is needed. As many have already pointed out, this is most likely due to missing definitions of virtual functions.
The bad thing, though, is, that the order of error messages may be counter-intuitive, with the "undefined reference to typeinfo" occuring before the undefined references to the missing virtual definitions. Here an example, that I just experienced:
/usr/bin/ld: module.o:(.data.rel.ro+0x10): undefined reference to `typeinfo for type_xxx' /usr/bin/ld: module.o:(.data.rel.ro+0x28): undefined reference to `typeinfo for type_xxx' /usr/bin/ld: module.o:(.data.rel.ro+0x40): undefined reference to `typeinfo for type_xxx' /usr/bin/ld: module.o:(.data.rel.ro+0x150): undefined reference to `type_xxx::has_property(std::__cxx11::basic_string, std::allocator > const&)'
So that missing definition of type_xxx::has_property(const std::string&) is only reported as the fourth error. So, sometimes it pays off to skip those error messages, that one doesn't understand, and handle the ones, first, that are easy to understand. Because in this case, adding the missing definitions then also fixes the problem with the undefined typeinfo references.