g++ undefined reference to typeinfo

220,585

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.

Share:
220,585

Related videos on Youtube

cdleary
Author by

cdleary

Updated on September 03, 2021

Comments

  • cdleary
    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
      Nav over 13 years
      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.
    • dhardy
      dhardy almost 12 years
      better yet as virtual void abc() =0; (if the base version is never called)
    • HelloGoodbye
      HelloGoodbye over 11 years
      @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.
    • Oleg Vazhnev
      Oleg Vazhnev over 9 years
      i 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
      dwanderson about 8 years
      GAH. 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
      Raghav Navada about 7 years
      In 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
    Alastair over 15 years
    Upmodded 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
    paxdiablo over 15 years
    One 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
    CesarB over 15 years
    You can use typeid without a vtable; see my answer for the quotes from the gcc manual.
  • AnT stands with Russia
    AnT stands with Russia almost 14 years
    It 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
    Chris Huang-Leaver over 13 years
    You 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
    Tatiana Racheva almost 13 years
    In 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
    steipete almost 13 years
    THANK YOU SO MUCH. That fixed my problem after 5 hour searching.
  • Sergiy Belozorov
    Sergiy Belozorov over 12 years
    @steipete: glad this is helpful :)
  • math
    math about 12 years
    source link is dead, it was surely the same as permalink.gmane.org/gmane.comp.gcc.help/32475
  • Sergiy Belozorov
    Sergiy Belozorov about 12 years
    Thanks for pointing this out. Original page is still available here: web.archive.org/web/20100503172629/http://www.pubbs.net/2010‌​04/…
  • Nawar
    Nawar about 11 years
    And sometimes one even must declare a body for a pure virtual function.
  • chmike
    chmike almost 11 years
    The 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
    spartygw over 10 years
    StackOverflow.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
    Admin almost 10 years
    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/…
  • malat
    malat almost 10 years
    feels like a hack, but it did solve the symptoms on my side. Thanks !
  • gbmhunter
    gbmhunter over 9 years
    I 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
    paxdiablo over 9 years
    @gbmhunter, fair enough. Made the change.
  • rholmes
    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
    Gabriel over 8 years
    n+1 lives saved and still counting :)
  • uwydoc
    uwydoc about 8 years
    pal, 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
    marsh almost 8 years
    This was it for me, linking to a library with different RTTI settings.
  • Irene
    Irene over 7 years
    Thank 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
    nnrales about 6 years
    I was only able to solve this error, when I set the virtual void fun() = 0. I missed the =0.
  • Guy Avraham
    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
    jaques-sam almost 5 years
    I 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
    PieterNuyts over 4 years
    In 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
    Fedor almost 3 years
    Actually linking order matters with clang as well, so this advice is universally applicable, thanks.
  • mostafa.elhoushi
    mostafa.elhoushi about 2 years
    Thanks. 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
  • Daemon42
    Daemon42 about 2 years
    Yes 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.