Undefined symbols "vtable for ..." and "typeinfo for..."?
Asked Answered
G

6

58

Nearly the final step but still some strange erros....

bash-3.2$ make
g++ -Wall -c -g Myworld.cc
g++ -Wall -g solvePlanningProblem.o Position.o AStarNode.o PRM.o PRMNode.o World.o SingleCircleWorld.o Myworld.o RECTANGLE.o CIRCLE.o -o solvePlanningProblem
Undefined symbols:
  "vtable for Obstacle", referenced from:
      Obstacle::Obstacle()in Myworld.o
  "typeinfo for Obstacle", referenced from:
      typeinfo for RECTANGLEin RECTANGLE.o
      typeinfo for CIRCLEin CIRCLE.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [solvePlanningProblem] Error 1

What's the meaning of vtable and typeinfo?

Gauger answered 7/11, 2009 at 16:43 Comment(4)
Remember to go back to your original question and post some code or answer some of the questions people have asked you there. That'll probably get you quicker results. :)Mother
i really want to but the site just missing , thanks ,i will go backGauger
please find the answer here ! #1458680Cassowary
Others mentioned the truth of what happened. However, despite that some virtual function not implemented, code file not put into the compiler source file list is also a possible reason :(.Net
M
107

If Obstacle is an abstract base class, then make sure you declare all its virtual methods "pure virtual":

virtual void Method() = 0;

The = 0 tells the compiler that this method must be overridden by a derived class, and might not have its own implementation.

If the class contains any non-pure virtual functions, then the compiler will assume that they have an implementation somewhere, and its internal structures (vtable and typeinfo) might be generated in the same object file as one of those; if those functions are not implemented, then the internal structures will be missing and you will get these errors.

Moly answered 7/11, 2009 at 17:31 Comment(3)
I just came across this problem in my own code. I found this page through Google search, and I made the change you said and it fixed it. Thanks! :DPawl
Same as above - found on google - solved problem right away, solution was quick and easy! I had added another pure virtual member to a list of virtual functions and forgot to add the = 0 token ! oopsLarcener
Note: an abstract class can have virtual methods with a "default" implementation (residing in the same base class) which a successor class may or may not override. If you want to use virtual methods like this, do not declare them "pure virtual" (= 0) in the base class.Intravenous
D
13

The class Obstacle needs a virtual destructor. Change the destructor definition to be:

virtual ~Obstacle();

The definition of a destructor also creates the vtable for a class with virtual functions. It also ensures that a delete of a derived class instance through a base class pointer does the right thing.

(copy of my answer to question What should I do with this strange error? which seems to be a duplicate.)

Delphinus answered 8/11, 2009 at 0:8 Comment(2)
In my case, I not only needed to define the destructor but also forgot to define the implementation in my cpp file.Erythroblastosis
I also need to define the implementation to make it workStele
A
13

There is another reason you can get this error, and just want to document it here. I was linking with a static library which did not have RTTI. So Using the C++ flag -fno-rtti fixed for me. If you do not need RTTI, you can using this flag as well. Hope this helps.

Aixenprovence answered 15/10, 2017 at 6:32 Comment(1)
Thank you so much for this! I had an error like: ld.lld: error: undefined symbol: typeinfo for MySuperClass >>> referenced by SubClass.cpp >>> SubClass.o:(typeinfo for ... in libcore.a) >>> did you mean: vtable for MySuperClass And it was due to me compiling one library with -fno-rtti but forgetting to set that when compiling the second library (which depended on the first)Aceldama
C
6

Do you have an Obstacle.cc file? If so, you need to make sure it gets built into Obstacle.o, and that Obstacle.o gets added to the command line when you link your program.

Also, make sure that you define all of the non-pure-virtual methods you declare. If you declare a pure virtual destructor, you need to define that too.

Coast answered 7/11, 2009 at 17:0 Comment(5)
must i have an Obstacle.cc, since it has only some virtual functions?Gauger
@Lisa: not necessarily, but defining non-inline non-template methods/functions in a .h file is likely to lead to a different linker error (multiple definitions). So I'll assume that everything in Obstacle is inline. Did you write definitions for all of Obstacle's member functions, including the constructor(s) and destructor? Note that if Obstacle has a pure virtual destructor, you are still required to write a definition for it.Coast
Does Obstacle have only pure virtual functions? Strike that--it doesn't matter when it comes to vtables. You need an Obstacle.o so the compiler has somewhere to store Obstacle's virtual table and type info.Barbuto
@outis: no, you don't need an object file. If all the virtual member functions are either inline or pure virtual, then the compiler must find somewhere to put the vtable. This typically done by generating a "link once" section in every object file.Moly
This solved the issue for me. I had created a new .cpp file with a new virtual destructor and forgot to add the file to Xcode's Compile Sources.Pignus
S
2

vtable and typeinfo are internal structures generated by the C++ compiler. vtable is used for calling virtuable functions and typeinfo is used for RTTI.

Different compilers have different strategies for when they generate these structures. One strategy I've seen is they will generate the table in the same object file that contains the first virtual function in the class.

Staciestack answered 7/11, 2009 at 16:51 Comment(1)
as far as the error above is concerned, what does undefined symbols mean ?Gauger
R
1

You can get this error if you mistakenly declare the method in your subclass but forget to implement it.

This can even happen if, as happened to me, you implement the method in an intermediate class. For example,

class Base {
public:
    virtual void func() = 0;
};

class Intermediate : public Base {
public:
    void func(); // implemented in source file
};

class Foo : public Intermediate {
    void func(); // not implemented and so a linker error will occur
};
Ruhnke answered 20/10, 2023 at 21:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.