I just ran across the following error:
(.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?
Can anyone explain what's going on behind the scenes?
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++.
Possible 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.
In 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".
In my case it was a virtual function in an interface class that wasn't defined as a pure virtual.
class IInterface
{
public:
virtual void Foo() = 0;
}
I forgot the = 0 bit.
Similarly 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.
I 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.
in 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.
I've got same error when my interface (with all pure virtual functions) needed one more function and I forgot to "null" it.
I had
class ICommProvider
{
public:
/**
* #brief If connection is established, it sends the message into the server.
* #param[in] msg - message to be send
* #return 0 if success, error otherwise
*/
virtual int vaSend(const std::string &msg) = 0;
/**
* #brief If connection is established, it is waiting will server response back.
* #param[out] msg is the message received from server
* #return 0 if success, error otherwise
*/
virtual int vaReceive(std::string &msg) = 0;
virtual int vaSendRaw(const char *buff, int bufflen) = 0;
virtual int vaReceiveRaw(char *buff, int bufflen) = 0;
/**
* #bief Closes current connection (if needed) after serving
* #return 0 if success, error otherwise
*/
virtual int vaClose();
};
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();
to
virtual int vaClose() = 0;
fixed the problem. hope it helps
I encounter an situation that is rare, but this may help other friends in similar situation. I have to work on an older system with gcc 4.4.7. I have to compile code with c++11 or above support, so I build the latest version of gcc 5.3.0. When building my code and linking to the dependencies if the dependency is build with older compiler, then I got 'undefined reference to' error even though I clearly defined the linking path with -L/path/to/lib -llibname. Some packages such as boost and projects build with cmake usually has a tendency to use the older compiler, and they usually cause such problems. You have to go a long way to make sure they use the newer compiler.
With 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<char, std::char_traits<char>, std::allocator<char> > 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.
Check that your dependencies were compiled without -f-nortti.
For some projects you have to set it explicitly, like in RocksDB:
USE_RTTI=1 make shared_lib -j4
In my case it is purely a library dependency issue even if I have dynamic_cast call. After adding enough dependency into makefile this problem was gone.
Related
When building my C++ program, I'm getting the error message
undefined reference to 'vtable...
What is the cause of this problem? How do I fix it?
It so happens that I'm getting the error for the following code (The class in question is CGameModule.) and I cannot for the life of me understand what the problem is. At first, I thought it was related to forgetting to give a virtual function a body, but as far as I understand, everything is all here. The inheritance chain is a little long, but here is the related source code. I'm not sure what other information I should provide.
Note: The constructor is where this error is happening, it'd seem.
My code:
class CGameModule : public CDasherModule {
public:
CGameModule(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName)
: CDasherModule(pEventHandler, pSettingsStore, iID, 0, szName)
{
g_pLogger->Log("Inside game module constructor");
m_pInterface = pInterface;
}
virtual ~CGameModule() {};
std::string GetTypedTarget();
std::string GetUntypedTarget();
bool DecorateView(CDasherView *pView) {
//g_pLogger->Log("Decorating the view");
return false;
}
void SetDasherModel(CDasherModel *pModel) { m_pModel = pModel; }
virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
CDasherNode *pLastTypedNode;
CDasherNode *pNextTargetNode;
std::string m_sTargetString;
size_t m_stCurrentStringPos;
CDasherModel *m_pModel;
CDasherInterfaceBase *m_pInterface;
};
Inherits from...
class CDasherModule;
typedef std::vector<CDasherModule*>::size_type ModuleID_t;
/// \ingroup Core
/// #{
class CDasherModule : public Dasher::CDasherComponent {
public:
CDasherModule(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, int iType, const char *szName);
virtual ModuleID_t GetID();
virtual void SetID(ModuleID_t);
virtual int GetType();
virtual const char *GetName();
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount) {
return false;
};
private:
ModuleID_t m_iID;
int m_iType;
const char *m_szName;
};
Which inherits from....
namespace Dasher {
class CEvent;
class CEventHandler;
class CDasherComponent;
};
/// \ingroup Core
/// #{
class Dasher::CDasherComponent {
public:
CDasherComponent(Dasher::CEventHandler* pEventHandler, CSettingsStore* pSettingsStore);
virtual ~CDasherComponent();
void InsertEvent(Dasher::CEvent * pEvent);
virtual void HandleEvent(Dasher::CEvent * pEvent) {};
bool GetBoolParameter(int iParameter) const;
void SetBoolParameter(int iParameter, bool bValue) const;
long GetLongParameter(int iParameter) const;
void SetLongParameter(int iParameter, long lValue) const;
std::string GetStringParameter(int iParameter) const;
void SetStringParameter(int iParameter, const std::string & sValue) const;
ParameterType GetParameterType(int iParameter) const;
std::string GetParameterName(int iParameter) const;
protected:
Dasher::CEventHandler *m_pEventHandler;
CSettingsStore *m_pSettingsStore;
};
/// #}
#endif
The GCC FAQ has an entry on it:
The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.
Therefore, you need to provide a definition for the virtual destructor:
virtual ~CDasherModule()
{ }
For what it is worth, forgetting a body on a virtual destructor generates the following:
undefined reference to `vtable for CYourClass'.
I am adding a note because the error message is deceptive. (This was with gcc version 4.6.3.)
TL;DR - Explains why the vtable might be missing and how to fix it. The answer is long because it explains why the compiler might forget to create a vtable. (Editor)
What is a vtable?
It might be useful to know what the error message is talking about before trying to fix it. I'll start at a high level, then work down to some more details. That way people can skip ahead once they are comfortable with their understanding of vtables. …and there goes a bunch of people skipping ahead right now. :) For those sticking around:
A vtable is basically the most common implementation of polymorphism in C++. When vtables are used, every polymorphic class has a vtable somewhere in the program; you can think of it as a (hidden) static data member of the class. Every object of a polymorphic class is associated with the vtable for its most-derived class. By checking this association, the program can work its polymorphic magic. Important caveat: a vtable is an implementation detail. It is not mandated by the C++ standard, even though most (all?) C++ compilers use vtables to implement polymorphic behavior. The details I am presenting are either typical or reasonable approaches. Compilers are allowed to deviate from this!
Each polymorphic object has a (hidden) pointer to the vtable for the object's most-derived class (possibly multiple pointers, in the more complex cases). By looking at the pointer, the program can tell what the "real" type of an object is (except during construction, but let's skip that special case). For example, if an object of type A does not point to the vtable of A, then that object is actually a sub-object of something derived from A.
The name "vtable" comes from "virtual function table". It is a table that stores pointers to (virtual) functions. A compiler chooses its convention for how the table is laid out; a simple approach is to go through the virtual functions in the order they are declared within class definitions. When a virtual function is called, the program follows the object's pointer to a vtable, goes to the entry associated with the desired function, then uses the stored function pointer to invoke the correct function. There are various tricks for making this work, but I won't go into those here.
Where/when is a vtable generated?
A vtable is automatically generated (sometimes called "emitted") by the compiler. A compiler could emit a vtable in every translation unit that sees a polymorphic class definition, but that would usually be unnecessary overkill. An alternative (used by gcc, and probably by others) is to pick a single translation unit in which to place the vtable, similar to how you would pick a single source file in which to put a class' static data members. If this selection process fails to pick any translation units, then the vtable becomes an undefined reference. Hence the error, whose message is admittedly not particularly clear.
Similarly, if the selection process does pick a translation unit, but that object file is not provided to the linker, then the vtable becomes an undefined reference. Unfortunately, the error message can be even less clear in this case than in the case where the selection process failed. (Thanks to the answerers who mentioned this possibility. I probably would have forgotten it otherwise.)
The selection process used by gcc makes sense if we start with the tradition of devoting a (single) source file to each class that needs one for its implementation. It would be nice to emit the vtable when compiling that source file. Let's call that our goal. However, the selection process needs to work even if this tradition is not followed. So instead of looking for the implementation of the entire class, let's look for the implementation of a specific member of the class. If tradition is followed – and if that member is in fact implemented – then this achieves the goal.
The member selected by gcc (and potentially by other compilers) is the first non-inline virtual function that is not pure virtual. If you are part of the crowd that declares constructors and destructors before other member functions, then that destructor has a good chance of being selected. (You did remember to make the destructor virtual, right?) There are exceptions; I'd expect that the most common exceptions are when an inline definition is provided for the destructor and when the default destructor is requested (using "= default").
The astute might notice that a polymorphic class is allowed to provide inline definitions for all of its virtual functions. Doesn't that cause the selection process to fail? It does in older compilers. I've read that the latest compilers have addressed this situation, but I do not know relevant version numbers. I could try looking this up, but it's easier to either code around it or wait for the compiler to complain.
In summary, there are three key causes of the "undefined reference to vtable" error:
A member function is missing its definition.
An object file is not being linked.
All virtual functions have inline definitions.
These causes are by themselves insufficient to cause the error on their own. Rather, these are what you would address to resolve the error. Do not expect that intentionally creating one of these situations will definitely produce this error; there are other requirements. Do expect that resolving these situations will resolve this error.
(OK, number 3 might have been sufficient when this question was asked.)
How to fix the error?
Welcome back people skipping ahead! :)
Look at your class definition. Find the first non-inline virtual function that is not pure virtual (not "= 0") and whose definition you provide (not "= default").
If there is no such function, try modifying your class so there is one. (Error possibly resolved.)
See also the answer by Philip Thomas for a caveat.
Find the definition for that function. If it is missing, add it! (Error possibly resolved.)
If the function definition is outside the class definition, then make sure the function definition uses a qualified name, as in ClassName::function_name.
Check your link command. If it does not mention the object file with that function's definition, fix that! (Error possibly resolved.)
Repeat steps 2 and 3 for each virtual function, then for each non-virtual function, until the error is resolved. If you're still stuck, repeat for each static data member.
Example
The details of what to do can vary, and sometimes branch off into separate questions (like What is an undefined reference/unresolved external symbol error and how do I fix it?). I will, though, provide an example of what to do in a specific case that might befuddle newer programmers.
Step 1 mentions modifying your class so that it has a function of a certain type. If the description of that function went over your head, you might be in the situation I intend to address. Keep in mind that this is a way to accomplish the goal; it is not the only way, and there easily could be better ways in your specific situation. Let's call your class A. Is your destructor declared (in your class definition) as either
virtual ~A() = default;
or
virtual ~A() {}
? If so, two steps will change your destructor into the type of function we want. First, change that line to
virtual ~A();
Second, put the following line in a source file that is part of your project (preferably the file with the class implementation, if you have one):
A::~A() {}
That makes your (virtual) destructor non-inline and not generated by the compiler. (Feel free to modify things to better match your code formatting style, such as adding a header comment to the function definition.)
So, I've figured out the issue and it was a combination of bad logic and not being totally familiar with the automake/autotools world. I was adding the correct files to my Makefile.am template, but I wasn't sure which step in our build process actually created the makefile itself. So, I was compiling with an old makefile that had no idea about my new files whatsoever.
Thanks for the responses and the link to the GCC FAQ. I will be sure to read that to avoid this problem occurring for a real reason.
If you are using Qt, try rerunning qmake. If this error is in the widget's class, qmake might have failed to notice that the ui class vtable should be regenerated. This fixed the issue for me.
Undefined reference to vtable may occur due to the following situation also. Just try this:
Class A Contains:
virtual void functionA(parameters)=0;
virtual void functionB(parameters);
Class B Contains:
The definition for the above functionA.
The definition for the above functionB.
Class C Contains: Now you're writing a Class C in which you are going to derive it from Class A.
Now if you try to compile you will get Undefined reference to vtable for Class C as error.
Reason:
functionA is defined as pure virtual and its definition is provided in Class B.
functionB is defined as virtual (NOT PURE VIRTUAL) so it tries to find its definition in Class A itself but you provided its definition in Class B.
Solution:
Make function B as pure virtual (if you have requirement like that)
virtual void functionB(parameters) =0;
(This works it is Tested)
Provide Definition for functionB in Class A itself keeping it as virtual .
(Hope it works as I didn't try this)
I simply got this error because my .cpp file was not in the makefile.
In general, if you forget to compile or link to the specific object file containing the definition, you will run into this error.
There is lot of speculation going on in various answers here. I'll below give a fairly minimal code that reproduces this error and explain why it is occuring.
Fairly Minimal Code to Reproduce This Error
IBase.hpp
#pragma once
class IBase {
public:
virtual void action() = 0;
};
Derived.hpp
#pragma once
#include "IBase.hpp"
class Derived : public IBase {
public:
Derived(int a);
void action() override;
};
Derived.cpp
#include "Derived.hpp"
Derived::Derived(int a) { }
void Derived::action() {}
myclass.cpp
#include <memory>
#include "Derived.hpp"
class MyClass {
public:
MyClass(std::shared_ptr<Derived> newInstance) : instance(newInstance) {
}
void doSomething() {
instance->action();
}
private:
std::shared_ptr<Derived> instance;
};
int main(int argc, char** argv) {
Derived myInstance(5);
MyClass c(std::make_shared<Derived>(myInstance));
c.doSomething();
return 0;
}
You can compile this using GCC like this:
g++ -std=c++11 -o a.out myclass.cpp Derived.cpp
You can now reproduce the error by removing = 0 in IBase.hpp. I get this error:
~/.../catkin_ws$ g++ -std=c++11 -o /tmp/m.out /tmp/myclass.cpp /tmp/Derived.cpp
/tmp/cclLscB9.o: In function `IBase::IBase(IBase const&)':
myclass.cpp:(.text._ZN5IBaseC2ERKS_[_ZN5IBaseC5ERKS_]+0x13): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o: In function `IBase::IBase()':
Derived.cpp:(.text._ZN5IBaseC2Ev[_ZN5IBaseC5Ev]+0xf): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o:(.rodata._ZTI7Derived[_ZTI7Derived]+0x10): undefined reference to `typeinfo for IBase'
collect2: error: ld returned 1 exit status
Explanation
Notice that above code does not require any virtual destructors, constructors or any other extra files for compile to be successful (although you should have them).
The way to understand this error is as follows:
Linker is looking for constructor of IBase. This it will need it for the constructor of Derived. However as Derived overrides methods from IBase, it has vtable attached to it that will reference IBase. When linker says "undefined reference to vtable for IBase" it basically means that Derived has vtable reference to IBase but it can't find any compiled object code of IBase to look up to. So the bottom line is that class IBase has declarations without implementations. This means a method in IBase is declared as virtual but we forgot to mark it as pure virtual OR provide its definition.
Parting Tip
If all else fails then one way to debug this error is to build minimal program that does compile and then keep changing it so it gets to the state you want. In between, keep compiling to see when it starts to fail.
Note on ROS and Catkin build system
If you were compiling above set of classes in ROS using catkin build system then you will need following lines in CMakeLists.txt:
add_executable(myclass src/myclass.cpp src/Derived.cpp)
add_dependencies(myclass theseus_myclass_cpp)
target_link_libraries(myclass ${catkin_LIBRARIES})
The first line basically says that we want to make an executable named myclass and the code to build this can be found files that follows. One of these files should have main(). Notice that you don't have to specify .hpp files anywhere in CMakeLists.txt. Also you don't have to specify Derived.cpp as library.
I just ran into another cause for this error that you can check for.
The base class defined a pure virtual function as:
virtual int foo(int x = 0);
And the subclass had
int foo(int x) override;
The problem was the typo that the "=0" was supposed to be outside of the parenthesis:
virtual int foo(int x) = 0;
So, in case you're scrolling this far down, you probably didn't find the answer - this is something else to check for.
The GNU C++ compiler has to make a decision where to put the vtable in case you have the definition of the virtual functions of an object spread across multiple compilations units (e.g. some of the objects virtual functions definitions are in a .cpp file others in another .cpp file, and so on).
The compiler chooses to put the vtable in the same place as where the first declared virtual function is defined.
Now if you for some reason forgot to provide a definition for that first virtual function declared in the object (or mistakenly forgot to add the compiled object at linking phase), you will get this error.
As a side effect, please note that only for this particular virtual function you won't get the traditional linker error like you are missing function foo.
Are you sure that CDasherComponent has a body for the destructor? It's definitely not here - the question is if it is in the .cc file.
From a style perspective, CDasherModule should explicitly define its destructor virtual.
It looks like CGameModule has an extra } at the end (after the }; // for the class).
Is CGameModule being linked against the libraries that define CDasherModule and CDasherComponent?
Not to cross post but. If you are dealing with inheritance the second google hit was what I had missed, ie. all virtual methods should be defined.
Such as:
virtual void fooBar() = 0;
See answare C++ Undefined Reference to vtable and inheritance for details. Just realized it's already mentioned above, but heck it might help someone.
For Qt User using CMakeList.txt
Add this line in your CMakeLists.txt : set(CMAKE_AUTOMOC ON)
As explain by Chris Morler if you forget to moc a header you get this error
So I was using Qt with Windows XP and MinGW compiler and this thing was driving me crazy.
Basically the moc_xxx.cpp was generated empty even when I was added
Q_OBJECT
Deleting everything making functions virtual, explicit and whatever you guess doesn't worked. Finally I started removing line by line and it turned out that I had
#ifdef something
Around the file. Even when the #ifdef was true moc file was not generated.
So removing all #ifdefs fixed the problem.
This thing was not happening with Windows and VS 2013.
In my case I'm using Qt and had defined a QObject subclass in a foo.cpp (not .h) file. The fix was to add #include "foo.moc" at the end of foo.cpp.
I think it's also worth mentioning that you will also get the message when you try to link to object of any class that has at least one virtual method and linker cannot find the file.
For example:
Foo.hpp:
class Foo
{
public:
virtual void StartFooing();
};
Foo.cpp:
#include "Foo.hpp"
void Foo::StartFooing(){ //fooing }
Compiled with:
g++ Foo.cpp -c
And main.cpp:
#include "Foo.hpp"
int main()
{
Foo foo;
}
Compiled and linked with:
g++ main.cpp -o main
Gives our favourite error:
/tmp/cclKnW0g.o: In function main': main.cpp:(.text+0x1a): undefined
reference tovtable for Foo' collect2: error: ld returned 1 exit
status
This occure from my undestanding becasue:
Vtable is created per class at compile time
Linker does not have access to vtable that is in Foo.o
If all else fails, look for duplication. I was misdirected by the explicit initial reference to constructors and destructors until I read a reference in another post. It's any unresolved method. In my case, I thought I had replaced the declaration that used char *xml as the parameter with one using the unnecessarily troublesome const char *xml, but instead, I had created a new one and left the other one in place.
This is a mis-feature in GCC. That is, the G++ compiler itself cannot complain about undefined virtual methods, since they can be defined elsewhere. But - it doesn't store information about which virtual members are missing; it only stores an UND-efined vtable symbol, which the linker then complains about.
Instead, if it were to list the missing members, the linker could have told you what they are.
There is an open bug about this issue against GCC: bug 42540. Unfortunately, it's 13-years-old :-(
I tried all the detailed steps by JaMIT and still got stumped by this error. After a good amount of head-banging, I figured it out. I was careless. You should be able to reproduce this painful-to-look-at error w/ the following sample code.
[jaswantp#jaswant-arch build]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (GCC)
// CelesetialBody.h
class CelestialBody{
public:
virtual void Print();
protected:
CelestialBody();
virtual ~CelestialBody();
};
// CelestialBody.cpp
#include "CelestialBody.h"
CelestialBody::CelestialBody() {}
CelestialBody::~CelestialBody() = default;
void CelestialBody::Print() {}
// Planet.h
#include "CelestialBody.h"
class Planet : public CelestialBody
{
public:
void Print() override;
protected:
Planet();
~Planet() override;
};
// Planet.cpp
#include "Planet.h"
Planet::Planet() {}
Planet::~Planet() {}
void Print() {} // Deliberately forgot to prefix `Planet::`
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project (space_engine)
add_library (CelestialBody SHARED CelestialBody.cpp)
add_library (Planet SHARED Planet.cpp)
target_include_directories (CelestialBody PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories (Planet PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries (Planet PUBLIC CelestialBody)
# hardened linker flags to catch undefined symbols
target_link_options(Planet
PRIVATE
-Wl,--as-needed
-Wl,--no-undefined
)
And we get our favourite error.
$ mkdir build
$ cd build
$ cmake ..
$ make
[ 50%] Built target CelestialBody
Scanning dependencies of target Planet
[ 75%] Building CXX object CMakeFiles/Planet.dir/Planet.cpp.o
[100%] Linking CXX shared library libPlanet.so
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::Planet()':
Planet.cpp:(.text+0x1b): undefined reference to `vtable for Planet'
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::~Planet()':
Planet.cpp:(.text+0x3d): undefined reference to `vtable for Planet'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Planet.dir/build.make:104: libPlanet.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/Planet.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
What I've done in Planet.cpp should of course be resolved with this tip
Look at your class definition. Find the first non-inline virtual function that is not pure virtual (not "= 0") and whose definition you provide (not "= default").
from JaMIT's answer.
If there is anyone else who tried all the above and nothing worked, maybe you too, like me, carelessly forgot to prefix <ClassName>:: to one or more member functions.
Either I need to get my eyes checked or I need to get some sleep.
I had this problem too when tried to implement Abstract Factory Pattern, but forgot to link some library. So, in case nothing was helped jet, check if all required libraries are linked
FWIW I was able to avoid errors like these:
ld: /usr/local/lib/libvmaf.a(svm.cpp.o):(.data.rel.ro._ZTI7QMatrix[_ZTI7QMatrix]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
When linking a "C" project with a static library from a "C++" project, by adding -lstdc++ to the linking parameters. So it's gcc -lstdc++ now it works.
Most common way is to add the -lstdc++ to the libraries pkgconfig .pc file Library list. Or link with g++ instead.
I created a test library called libmathClass.so which I will be loading from the code below. This shared object has a class and library call is created to return object of this class.
How can I call the methods of this object from the main code displayed below. I get undefined reference error from ld(linker) as it is not aware of the definition of methods.
void* handle;
handle=dlopen("math1/libmathClass.so", RTLD_LAZY);
if(!handle)
{
cout<<"error loading library: "<<dlerror()<<endl;
exit(2);
}
else
{
cout<<"***libmathClass.so library load successful!"<<endl;
}
void* (*mathInit) ();
mathInit = (void* (*)())dlsym(handle, "CreateMathOperationInstance");
if(!mathInit)
{
cout<<"error loading instance method: "<<dlerror()<<endl;
exit(3);
}
else
{
cout<<"***method load successful!"<<endl;
}
mathOperationClass *mathInstance;
auto obj = (*mathInit)();
if(!obj)
{
cout<<"object is not created"<<endl;
exit(4);
}
else
{
cout<<"object created!!!"<<endl;
mathInstance = reinterpret_cast<mathOperationClass *>(obj);
}
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
cout<< mathInstance->AddInt(num1, num2)<<endl;
Command I used to compile - g++ --std=c++11 -g -o dynamicTest dynamicMain.cpp -ldl
Error message:
dynamicMain.cpp:54: undefined reference to `mathOperationClass::AddInt(int, int)'
collect2: error: ld returned 1 exit status
mathInit = (void* (*)())dlsym(handle, "CreateMathOperationInstance");
Here you are using dlsym() to find this symbol in the shared library. This must be a function with C linkage, since the symbol name is not mangled. This is important, and keep this in mind, while you're staring at this line:
cout<< mathInstance->AddInt(num1, num2)<<endl;
Here, AddInt is a method of the class pointed to by mathInstance. A class method is just another function, except that it always takes a hidden this pointer as an extra argument. That's what a class method is, in so many words, and this actually turns out to be the case with a typical C++ implementation. C++ technically does not actually require this to be the case. A C++ implementation is free to implement methods in whatever manner produces the results that are compliant with the C++ specification. But, in practical terms, in a typical C++ implementation this is what a class method actually is. A function with an extra parameter that's referenced as this.
Therefore, in a manner of speaking, the above line is basically equivalent to:
cout<< mathOperationClass::AddInt(mathInstance, num1, num2)<<endl;
This basically is what's going on here, speaking very loosely.
This mathOperationClass::AddInt method/function is, presumably, in the same shared library that you dlopen-ed; and because you dlopen-ed it and you did not actually link to it, you have a reference to this symbol, and this reference cannot be resolved at runtime, hence your runtime undefined symbol error.
The only way you can even the slightest hope of invoking this class method -- if it can be invoked at all in this manner -- is by also using dlsym(). But in order to have even the slightest prayer of actually being be able to pull this off, a whole bunch of things need to happen just right.
First, you have to figure out the actual mangled C++ symbol name. Using my Linux x86_64 g++ compiler as a reference, the mangled name for this method would be "_ZN18mathOperationClass6AddIntEii". With that in hand, you can use dlsym to find this symbol (or whatever your C++ implementation's actual mangled symbol name for this method is) in your shared library.
And once you have this symbol, what now? Well, let's hope that your C++ implementation does, indeed, have a hackable C++ ABI where you can invoke a class method by explicitly passing it an extra this parameter, something like this:
int (*addInt)(mathOperationClass *, int, int)=
reinterpret_cast<int (*)(mathOperationClass *, int, int)>
(dlsym(handle, "_ZN18mathOperationClass6AddIntEii"));
cout << (*addInt)(mathInstance, num1, num2) << endl;
This entire house of cards will collapse unless it can be confirmed that C++ methods can be invoked this hackish way, in your C++ implementation's ABI. Since you're already using dlopen() you're already in non-portable territory, using your C++ implementation-specific resources, so you might as well and figure out whether your C++ methods can be called this way. If not, you'll have to figure out how they can be called, using a plain pointer.
And now for something completely different...
Having said all of the above:
There is one way you can likely avoid dealing with this mess: by making this class method a virtual class method. Virtual class methods are dispatched via an internal virtual function table. So, just try declaring this AddInt method as a virtual class method, and calling it, as is. It's very likely to work in your C++ implementation, since the compiler will not emit, in this instance, an explicit symbol reference for mathOperationClass::AddInt. It will find the method via the virtual function table that's quietly attached to every instance of the object.
Of course, you also need to keep in mind what virtual functions are, and the implications of them. But, in nearly all cases this is a pretty cheap way to call methods of classes that are dynamically loaded from a shared library.
When building my C++ program, I'm getting the error message
undefined reference to 'vtable...
What is the cause of this problem? How do I fix it?
It so happens that I'm getting the error for the following code (The class in question is CGameModule.) and I cannot for the life of me understand what the problem is. At first, I thought it was related to forgetting to give a virtual function a body, but as far as I understand, everything is all here. The inheritance chain is a little long, but here is the related source code. I'm not sure what other information I should provide.
Note: The constructor is where this error is happening, it'd seem.
My code:
class CGameModule : public CDasherModule {
public:
CGameModule(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName)
: CDasherModule(pEventHandler, pSettingsStore, iID, 0, szName)
{
g_pLogger->Log("Inside game module constructor");
m_pInterface = pInterface;
}
virtual ~CGameModule() {};
std::string GetTypedTarget();
std::string GetUntypedTarget();
bool DecorateView(CDasherView *pView) {
//g_pLogger->Log("Decorating the view");
return false;
}
void SetDasherModel(CDasherModel *pModel) { m_pModel = pModel; }
virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
CDasherNode *pLastTypedNode;
CDasherNode *pNextTargetNode;
std::string m_sTargetString;
size_t m_stCurrentStringPos;
CDasherModel *m_pModel;
CDasherInterfaceBase *m_pInterface;
};
Inherits from...
class CDasherModule;
typedef std::vector<CDasherModule*>::size_type ModuleID_t;
/// \ingroup Core
/// #{
class CDasherModule : public Dasher::CDasherComponent {
public:
CDasherModule(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, int iType, const char *szName);
virtual ModuleID_t GetID();
virtual void SetID(ModuleID_t);
virtual int GetType();
virtual const char *GetName();
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount) {
return false;
};
private:
ModuleID_t m_iID;
int m_iType;
const char *m_szName;
};
Which inherits from....
namespace Dasher {
class CEvent;
class CEventHandler;
class CDasherComponent;
};
/// \ingroup Core
/// #{
class Dasher::CDasherComponent {
public:
CDasherComponent(Dasher::CEventHandler* pEventHandler, CSettingsStore* pSettingsStore);
virtual ~CDasherComponent();
void InsertEvent(Dasher::CEvent * pEvent);
virtual void HandleEvent(Dasher::CEvent * pEvent) {};
bool GetBoolParameter(int iParameter) const;
void SetBoolParameter(int iParameter, bool bValue) const;
long GetLongParameter(int iParameter) const;
void SetLongParameter(int iParameter, long lValue) const;
std::string GetStringParameter(int iParameter) const;
void SetStringParameter(int iParameter, const std::string & sValue) const;
ParameterType GetParameterType(int iParameter) const;
std::string GetParameterName(int iParameter) const;
protected:
Dasher::CEventHandler *m_pEventHandler;
CSettingsStore *m_pSettingsStore;
};
/// #}
#endif
The GCC FAQ has an entry on it:
The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.
Therefore, you need to provide a definition for the virtual destructor:
virtual ~CDasherModule()
{ }
For what it is worth, forgetting a body on a virtual destructor generates the following:
undefined reference to `vtable for CYourClass'.
I am adding a note because the error message is deceptive. (This was with gcc version 4.6.3.)
TL;DR - Explains why the vtable might be missing and how to fix it. The answer is long because it explains why the compiler might forget to create a vtable. (Editor)
What is a vtable?
It might be useful to know what the error message is talking about before trying to fix it. I'll start at a high level, then work down to some more details. That way people can skip ahead once they are comfortable with their understanding of vtables. …and there goes a bunch of people skipping ahead right now. :) For those sticking around:
A vtable is basically the most common implementation of polymorphism in C++. When vtables are used, every polymorphic class has a vtable somewhere in the program; you can think of it as a (hidden) static data member of the class. Every object of a polymorphic class is associated with the vtable for its most-derived class. By checking this association, the program can work its polymorphic magic. Important caveat: a vtable is an implementation detail. It is not mandated by the C++ standard, even though most (all?) C++ compilers use vtables to implement polymorphic behavior. The details I am presenting are either typical or reasonable approaches. Compilers are allowed to deviate from this!
Each polymorphic object has a (hidden) pointer to the vtable for the object's most-derived class (possibly multiple pointers, in the more complex cases). By looking at the pointer, the program can tell what the "real" type of an object is (except during construction, but let's skip that special case). For example, if an object of type A does not point to the vtable of A, then that object is actually a sub-object of something derived from A.
The name "vtable" comes from "virtual function table". It is a table that stores pointers to (virtual) functions. A compiler chooses its convention for how the table is laid out; a simple approach is to go through the virtual functions in the order they are declared within class definitions. When a virtual function is called, the program follows the object's pointer to a vtable, goes to the entry associated with the desired function, then uses the stored function pointer to invoke the correct function. There are various tricks for making this work, but I won't go into those here.
Where/when is a vtable generated?
A vtable is automatically generated (sometimes called "emitted") by the compiler. A compiler could emit a vtable in every translation unit that sees a polymorphic class definition, but that would usually be unnecessary overkill. An alternative (used by gcc, and probably by others) is to pick a single translation unit in which to place the vtable, similar to how you would pick a single source file in which to put a class' static data members. If this selection process fails to pick any translation units, then the vtable becomes an undefined reference. Hence the error, whose message is admittedly not particularly clear.
Similarly, if the selection process does pick a translation unit, but that object file is not provided to the linker, then the vtable becomes an undefined reference. Unfortunately, the error message can be even less clear in this case than in the case where the selection process failed. (Thanks to the answerers who mentioned this possibility. I probably would have forgotten it otherwise.)
The selection process used by gcc makes sense if we start with the tradition of devoting a (single) source file to each class that needs one for its implementation. It would be nice to emit the vtable when compiling that source file. Let's call that our goal. However, the selection process needs to work even if this tradition is not followed. So instead of looking for the implementation of the entire class, let's look for the implementation of a specific member of the class. If tradition is followed – and if that member is in fact implemented – then this achieves the goal.
The member selected by gcc (and potentially by other compilers) is the first non-inline virtual function that is not pure virtual. If you are part of the crowd that declares constructors and destructors before other member functions, then that destructor has a good chance of being selected. (You did remember to make the destructor virtual, right?) There are exceptions; I'd expect that the most common exceptions are when an inline definition is provided for the destructor and when the default destructor is requested (using "= default").
The astute might notice that a polymorphic class is allowed to provide inline definitions for all of its virtual functions. Doesn't that cause the selection process to fail? It does in older compilers. I've read that the latest compilers have addressed this situation, but I do not know relevant version numbers. I could try looking this up, but it's easier to either code around it or wait for the compiler to complain.
In summary, there are three key causes of the "undefined reference to vtable" error:
A member function is missing its definition.
An object file is not being linked.
All virtual functions have inline definitions.
These causes are by themselves insufficient to cause the error on their own. Rather, these are what you would address to resolve the error. Do not expect that intentionally creating one of these situations will definitely produce this error; there are other requirements. Do expect that resolving these situations will resolve this error.
(OK, number 3 might have been sufficient when this question was asked.)
How to fix the error?
Welcome back people skipping ahead! :)
Look at your class definition. Find the first non-inline virtual function that is not pure virtual (not "= 0") and whose definition you provide (not "= default").
If there is no such function, try modifying your class so there is one. (Error possibly resolved.)
See also the answer by Philip Thomas for a caveat.
Find the definition for that function. If it is missing, add it! (Error possibly resolved.)
If the function definition is outside the class definition, then make sure the function definition uses a qualified name, as in ClassName::function_name.
Check your link command. If it does not mention the object file with that function's definition, fix that! (Error possibly resolved.)
Repeat steps 2 and 3 for each virtual function, then for each non-virtual function, until the error is resolved. If you're still stuck, repeat for each static data member.
Example
The details of what to do can vary, and sometimes branch off into separate questions (like What is an undefined reference/unresolved external symbol error and how do I fix it?). I will, though, provide an example of what to do in a specific case that might befuddle newer programmers.
Step 1 mentions modifying your class so that it has a function of a certain type. If the description of that function went over your head, you might be in the situation I intend to address. Keep in mind that this is a way to accomplish the goal; it is not the only way, and there easily could be better ways in your specific situation. Let's call your class A. Is your destructor declared (in your class definition) as either
virtual ~A() = default;
or
virtual ~A() {}
? If so, two steps will change your destructor into the type of function we want. First, change that line to
virtual ~A();
Second, put the following line in a source file that is part of your project (preferably the file with the class implementation, if you have one):
A::~A() {}
That makes your (virtual) destructor non-inline and not generated by the compiler. (Feel free to modify things to better match your code formatting style, such as adding a header comment to the function definition.)
So, I've figured out the issue and it was a combination of bad logic and not being totally familiar with the automake/autotools world. I was adding the correct files to my Makefile.am template, but I wasn't sure which step in our build process actually created the makefile itself. So, I was compiling with an old makefile that had no idea about my new files whatsoever.
Thanks for the responses and the link to the GCC FAQ. I will be sure to read that to avoid this problem occurring for a real reason.
If you are using Qt, try rerunning qmake. If this error is in the widget's class, qmake might have failed to notice that the ui class vtable should be regenerated. This fixed the issue for me.
Undefined reference to vtable may occur due to the following situation also. Just try this:
Class A Contains:
virtual void functionA(parameters)=0;
virtual void functionB(parameters);
Class B Contains:
The definition for the above functionA.
The definition for the above functionB.
Class C Contains: Now you're writing a Class C in which you are going to derive it from Class A.
Now if you try to compile you will get Undefined reference to vtable for Class C as error.
Reason:
functionA is defined as pure virtual and its definition is provided in Class B.
functionB is defined as virtual (NOT PURE VIRTUAL) so it tries to find its definition in Class A itself but you provided its definition in Class B.
Solution:
Make function B as pure virtual (if you have requirement like that)
virtual void functionB(parameters) =0;
(This works it is Tested)
Provide Definition for functionB in Class A itself keeping it as virtual .
(Hope it works as I didn't try this)
I simply got this error because my .cpp file was not in the makefile.
In general, if you forget to compile or link to the specific object file containing the definition, you will run into this error.
There is lot of speculation going on in various answers here. I'll below give a fairly minimal code that reproduces this error and explain why it is occuring.
Fairly Minimal Code to Reproduce This Error
IBase.hpp
#pragma once
class IBase {
public:
virtual void action() = 0;
};
Derived.hpp
#pragma once
#include "IBase.hpp"
class Derived : public IBase {
public:
Derived(int a);
void action() override;
};
Derived.cpp
#include "Derived.hpp"
Derived::Derived(int a) { }
void Derived::action() {}
myclass.cpp
#include <memory>
#include "Derived.hpp"
class MyClass {
public:
MyClass(std::shared_ptr<Derived> newInstance) : instance(newInstance) {
}
void doSomething() {
instance->action();
}
private:
std::shared_ptr<Derived> instance;
};
int main(int argc, char** argv) {
Derived myInstance(5);
MyClass c(std::make_shared<Derived>(myInstance));
c.doSomething();
return 0;
}
You can compile this using GCC like this:
g++ -std=c++11 -o a.out myclass.cpp Derived.cpp
You can now reproduce the error by removing = 0 in IBase.hpp. I get this error:
~/.../catkin_ws$ g++ -std=c++11 -o /tmp/m.out /tmp/myclass.cpp /tmp/Derived.cpp
/tmp/cclLscB9.o: In function `IBase::IBase(IBase const&)':
myclass.cpp:(.text._ZN5IBaseC2ERKS_[_ZN5IBaseC5ERKS_]+0x13): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o: In function `IBase::IBase()':
Derived.cpp:(.text._ZN5IBaseC2Ev[_ZN5IBaseC5Ev]+0xf): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o:(.rodata._ZTI7Derived[_ZTI7Derived]+0x10): undefined reference to `typeinfo for IBase'
collect2: error: ld returned 1 exit status
Explanation
Notice that above code does not require any virtual destructors, constructors or any other extra files for compile to be successful (although you should have them).
The way to understand this error is as follows:
Linker is looking for constructor of IBase. This it will need it for the constructor of Derived. However as Derived overrides methods from IBase, it has vtable attached to it that will reference IBase. When linker says "undefined reference to vtable for IBase" it basically means that Derived has vtable reference to IBase but it can't find any compiled object code of IBase to look up to. So the bottom line is that class IBase has declarations without implementations. This means a method in IBase is declared as virtual but we forgot to mark it as pure virtual OR provide its definition.
Parting Tip
If all else fails then one way to debug this error is to build minimal program that does compile and then keep changing it so it gets to the state you want. In between, keep compiling to see when it starts to fail.
Note on ROS and Catkin build system
If you were compiling above set of classes in ROS using catkin build system then you will need following lines in CMakeLists.txt:
add_executable(myclass src/myclass.cpp src/Derived.cpp)
add_dependencies(myclass theseus_myclass_cpp)
target_link_libraries(myclass ${catkin_LIBRARIES})
The first line basically says that we want to make an executable named myclass and the code to build this can be found files that follows. One of these files should have main(). Notice that you don't have to specify .hpp files anywhere in CMakeLists.txt. Also you don't have to specify Derived.cpp as library.
I just ran into another cause for this error that you can check for.
The base class defined a pure virtual function as:
virtual int foo(int x = 0);
And the subclass had
int foo(int x) override;
The problem was the typo that the "=0" was supposed to be outside of the parenthesis:
virtual int foo(int x) = 0;
So, in case you're scrolling this far down, you probably didn't find the answer - this is something else to check for.
The GNU C++ compiler has to make a decision where to put the vtable in case you have the definition of the virtual functions of an object spread across multiple compilations units (e.g. some of the objects virtual functions definitions are in a .cpp file others in another .cpp file, and so on).
The compiler chooses to put the vtable in the same place as where the first declared virtual function is defined.
Now if you for some reason forgot to provide a definition for that first virtual function declared in the object (or mistakenly forgot to add the compiled object at linking phase), you will get this error.
As a side effect, please note that only for this particular virtual function you won't get the traditional linker error like you are missing function foo.
Are you sure that CDasherComponent has a body for the destructor? It's definitely not here - the question is if it is in the .cc file.
From a style perspective, CDasherModule should explicitly define its destructor virtual.
It looks like CGameModule has an extra } at the end (after the }; // for the class).
Is CGameModule being linked against the libraries that define CDasherModule and CDasherComponent?
Not to cross post but. If you are dealing with inheritance the second google hit was what I had missed, ie. all virtual methods should be defined.
Such as:
virtual void fooBar() = 0;
See answare C++ Undefined Reference to vtable and inheritance for details. Just realized it's already mentioned above, but heck it might help someone.
For Qt User using CMakeList.txt
Add this line in your CMakeLists.txt : set(CMAKE_AUTOMOC ON)
As explain by Chris Morler if you forget to moc a header you get this error
So I was using Qt with Windows XP and MinGW compiler and this thing was driving me crazy.
Basically the moc_xxx.cpp was generated empty even when I was added
Q_OBJECT
Deleting everything making functions virtual, explicit and whatever you guess doesn't worked. Finally I started removing line by line and it turned out that I had
#ifdef something
Around the file. Even when the #ifdef was true moc file was not generated.
So removing all #ifdefs fixed the problem.
This thing was not happening with Windows and VS 2013.
In my case I'm using Qt and had defined a QObject subclass in a foo.cpp (not .h) file. The fix was to add #include "foo.moc" at the end of foo.cpp.
I think it's also worth mentioning that you will also get the message when you try to link to object of any class that has at least one virtual method and linker cannot find the file.
For example:
Foo.hpp:
class Foo
{
public:
virtual void StartFooing();
};
Foo.cpp:
#include "Foo.hpp"
void Foo::StartFooing(){ //fooing }
Compiled with:
g++ Foo.cpp -c
And main.cpp:
#include "Foo.hpp"
int main()
{
Foo foo;
}
Compiled and linked with:
g++ main.cpp -o main
Gives our favourite error:
/tmp/cclKnW0g.o: In function main': main.cpp:(.text+0x1a): undefined
reference tovtable for Foo' collect2: error: ld returned 1 exit
status
This occure from my undestanding becasue:
Vtable is created per class at compile time
Linker does not have access to vtable that is in Foo.o
If all else fails, look for duplication. I was misdirected by the explicit initial reference to constructors and destructors until I read a reference in another post. It's any unresolved method. In my case, I thought I had replaced the declaration that used char *xml as the parameter with one using the unnecessarily troublesome const char *xml, but instead, I had created a new one and left the other one in place.
This is a mis-feature in GCC. That is, the G++ compiler itself cannot complain about undefined virtual methods, since they can be defined elsewhere. But - it doesn't store information about which virtual members are missing; it only stores an UND-efined vtable symbol, which the linker then complains about.
Instead, if it were to list the missing members, the linker could have told you what they are.
There is an open bug about this issue against GCC: bug 42540. Unfortunately, it's 13-years-old :-(
I tried all the detailed steps by JaMIT and still got stumped by this error. After a good amount of head-banging, I figured it out. I was careless. You should be able to reproduce this painful-to-look-at error w/ the following sample code.
[jaswantp#jaswant-arch build]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-libunwind-exceptions --disable-werror gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (GCC)
// CelesetialBody.h
class CelestialBody{
public:
virtual void Print();
protected:
CelestialBody();
virtual ~CelestialBody();
};
// CelestialBody.cpp
#include "CelestialBody.h"
CelestialBody::CelestialBody() {}
CelestialBody::~CelestialBody() = default;
void CelestialBody::Print() {}
// Planet.h
#include "CelestialBody.h"
class Planet : public CelestialBody
{
public:
void Print() override;
protected:
Planet();
~Planet() override;
};
// Planet.cpp
#include "Planet.h"
Planet::Planet() {}
Planet::~Planet() {}
void Print() {} // Deliberately forgot to prefix `Planet::`
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project (space_engine)
add_library (CelestialBody SHARED CelestialBody.cpp)
add_library (Planet SHARED Planet.cpp)
target_include_directories (CelestialBody PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories (Planet PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries (Planet PUBLIC CelestialBody)
# hardened linker flags to catch undefined symbols
target_link_options(Planet
PRIVATE
-Wl,--as-needed
-Wl,--no-undefined
)
And we get our favourite error.
$ mkdir build
$ cd build
$ cmake ..
$ make
[ 50%] Built target CelestialBody
Scanning dependencies of target Planet
[ 75%] Building CXX object CMakeFiles/Planet.dir/Planet.cpp.o
[100%] Linking CXX shared library libPlanet.so
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::Planet()':
Planet.cpp:(.text+0x1b): undefined reference to `vtable for Planet'
/usr/bin/ld: CMakeFiles/Planet.dir/Planet.cpp.o: in function `Planet::~Planet()':
Planet.cpp:(.text+0x3d): undefined reference to `vtable for Planet'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Planet.dir/build.make:104: libPlanet.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/Planet.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
What I've done in Planet.cpp should of course be resolved with this tip
Look at your class definition. Find the first non-inline virtual function that is not pure virtual (not "= 0") and whose definition you provide (not "= default").
from JaMIT's answer.
If there is anyone else who tried all the above and nothing worked, maybe you too, like me, carelessly forgot to prefix <ClassName>:: to one or more member functions.
Either I need to get my eyes checked or I need to get some sleep.
I had this problem too when tried to implement Abstract Factory Pattern, but forgot to link some library. So, in case nothing was helped jet, check if all required libraries are linked
FWIW I was able to avoid errors like these:
ld: /usr/local/lib/libvmaf.a(svm.cpp.o):(.data.rel.ro._ZTI7QMatrix[_ZTI7QMatrix]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
When linking a "C" project with a static library from a "C++" project, by adding -lstdc++ to the linking parameters. So it's gcc -lstdc++ now it works.
Most common way is to add the -lstdc++ to the libraries pkgconfig .pc file Library list. Or link with g++ instead.
I am developing code for an embedded system (specifically, the PSoC 5, using PSoC Creator), and writing in C++.
While I've overcome most hurdles with using C++ , first off compiling in C++ using the compiler flag -x c++, defining the new and delete operators, making sure exceptions aren't thrown with the compiler flag -fno-exception, I've come to a brick wall when it comes to using virtual functions.
If I try and declare a virtual function, the compiler gives me the error undefined reference to "vtable for __cxxabiv1::__class_type_info". The only way to get around this is to use the compiler flag -fno-rtti, which prevents the error and makes it compile successfully. However, if I do that, the embedded program crashes when trying to run the overloaded virtual function, and I'm thinking this is because the vtable does not exist.
I don't see why you shouldn't be able to implement vtables on an embedded platform, since all it is a extra space in memory before or after member objects (depending on the exact compiler).
The reason I am trying to use virtual functions is because I am wanting to use FreeRTOS with C++, and other people have implemented this by using virtual functions (see http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html for the discussion, and https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems for a well written embedded C++ FreeRTOS framework)
The fact that the error message refers to a class named __cxxabiv1 suggests that you are not linking against the correct C++ runtime for your platform. I don't know anything about PSoC, but on more "normal" platforms, this sort of error could happen if you used the gcc (resp. clang) command at link-time instead of g++ (resp. clang++); or under handwavey circumstances if you used -lc++ without -stdlib=libc++ or -lstdc++ without -stdlib=libstdc++.
Use the -v option to examine your linker command line, and try to find out exactly which C++ runtime library it's pulling in. It'll probably be named something like libcxxabi or libcxxrt.
This guy here gives step-by-step instructions for compiling C++ in PSoC Creator; but he never figured out how to link with a C++ runtime library, so all his tips are focused on how to remove C++isms from your code (-fno-rtti, -fno-exceptions,...). I agree that there doesn't seem to be any information online about how to actually use C++ with PSoC.
For this specific error, you could always try defining the missing symbol yourself:
// file "fix-link-errors.cpp"
namespace __cxxabiv1 {
class __class_type_info {
virtual void dummy();
};
void __class_type_info::dummy() { } // causes the vtable to get created here
};
Or many linkers have the ability to define undefined symbols as 0x0 through command-line options such as -C or --defsym. However, that's not only a Bad Idea but also inconvenient, because you'd have to figure out what the actual (mangled) name of the vtable object is, and the linker didn't tell you that. (This being GCC, it's probably something like __ZTVN10__cxxabiv117__class_type_infoE.)
Either of those "solutions" would result in horrible crashes if the program ever tried to do anything with the vtable; but they'd shut the linker up, if that's all you cared about and you knew the program would never actually use RTTI. But in that case, it should be sufficient to use -fno-rtti consistently on your entire project.
What, specifically, goes wrong when you use -fno-rtti?
Whilst compiling with avr-gcc I have encountered linker errors such as the following:
undefined reference to `__cxa_pure_virtual'
I've found this document which states:
The __cxa_pure_virtual function is an error handler that is invoked when a pure virtual function is called.
If you are writing a C++ application that has pure virtual functions you must supply your own __cxa_pure_virtual error handler function. For example:
extern "C" void __cxa_pure_virtual() { while (1); }
Defining this function as suggested fixes the errors but I'd like to know:
what the purpose of this function is,
why I should need to define it myself and
why it is acceptable to code it as an infinite loop?
If anywhere in the runtime of your program an object is created with a virtual function pointer not filled in, and when the corresponding function is called, you will be calling a 'pure virtual function'.
The handler you describe should be defined in the default libraries that come with your development environment. If you happen to omit the default libraries, you will find this handler undefined: the linker sees a declaration, but no definition. That's when you need to provide your own version.
The infinite loop is acceptable because it's a 'loud' error: users of your software will immediately notice it. Any other 'loud' implementation is acceptable, too.
1) What's the purpose of the function __cxa_pure_virtual()?
Pure virtual functions can get called during object construction/destruction. If that happens, __cxa_pure_virtual() gets called to report the error. See Where do "pure virtual function call" crashes come from?
2) Why might you need to define it yourself?
Normally this function is provided by libstdc++ (e.g. on Linux), but avr-gcc and the Arduino toolchain don't provide a libstdc++.
The Arduino IDE manages to avoid the linker error when building some programs because it compiles with the options "-ffunction-sections -fdata-sections" and links with "-Wl,--gc-sections", which drops some references to unused symbols.
3) Why is it acceptable to code __cxa_pure_virtual() as an infinite loop?
Well, this is at least safe; it does something predictable. It would be more useful to abort the program and report the error. An infinite loop would be awkward to debug, though, unless you have a debugger that can interrupt execution and give a stack backtrace.