Vtable ran away - c++

class MedicineRepository
{
public:
virtual Medicine* findById(int medId) ;
virtual Vector<Medicine*> getAll() ;
virtual int getNrMeds() ;
virtual void addMed(Medicine s) ;
virtual void removeMed(int medId) ;
virtual ~MedicineRepository() ;
};
undefined reference to vtable for MedicineRepository' is the error I get in this class.I'm inheriting this class in another module and looks like this in the header:
class MedRepo : public MedicineRepository{
public: ~MedRepo();
...
};
and in the cpp it's defined as :
MedRepo::~MedRepo()
{}
I don't understand it and I've already looked for something usefull in Undefined reference to vtable

I don't think you've posted enough of the error output for anyone to meaningfully determine what the problem is - are you getting it in every file that includes the header, or are you getting it on a specific line of code? In which file? Did you implement the body for ~MedicineRepository?
I would suggest you take a copy of the code, remove as much functionality from the implementations as possible, strip it down to the minimum set of definitions that still generates the error, and then if that doesn't help you solve it, post that.

Related

c++ undefined reference to vtable exception [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I've searched many answers but none of them can solve my problem, I'm new to c++, this issue is quite wired to me. Below is a simplified extraction of my code.
TestHeader.h:
#ifndef NAMESPACE_TESTHEADER_H_
#define NAMESPACE_TESTHEADER__H_
namespace Namespace {
class TestHeader {
public:
TestHeader(const std::string& str) : anyString_(str) { }
virtual std::string methodOne(const std::string& param) const;
virtual ~TestHeader() { anyString_.clear(); }
protected:
std::string anyString_;
};
}
#endif //NAMESPACE_TESTHEADER__H_
TestHeader.cpp:
#include "TestHeader.h"
using namespace std;
namespace Namespace {
TestHeader::TestHeader(const std::string& str):anyString_(str) { <do something>; }
std::string TestHeader::methodOne(const std::string& param) const
{
return <A string>;
}
TestHeader::~TestHeader() {
anyString_.clear();
}
}
What I did was simply call this line in any other .cpp in my package:
#include "TestHeader.h"
TestHeader testHeader("whatever");
The build failed by throwing
error: undefined reference to 'vtable for Namespace::TestHeader'
the vtable symbol may be undefined because the class is missing its key function
The most weird thing is: if I comment out virtual std::string methodOne(const std::string& str) const; in header and its implementation in .cpp, OR, if I comment out : anyString_(str) after constructor and anyString_.clear(); in destructor together in header only, the build will succeed.
Firstly You should not define the constructor and destructor twice. It shouldn't be compiling as mentioned by Curious in comments
Second I assume that you want don't the class to be abstract as there is no Runtime polymorphism implemented which is the basic use of Virtual functions.
If you don't want the class TestHeader to be abstract remove the virtual keyword which is referring to Virtual Table.C++ compiler inserts Virtual Table for every class having virtual function or class inherited from the class that has virtual functions.
Better study the use of Virtual keyword and then write the code.
Here are quick links for the same
Link 1
Link 2
Also, I think you need to revisit few concepts from Destructor virtual ~TestHeader() { anyString_.clear(); } does not make any sense. In fact, there is no base class which in turn denies the use of Virtual Destructor which is used in case of Inheritance
Firstly, include #include <string> at the top of your header file. I am guessing the error is because you have not linked the object file produced after compiling TestHeader.cpp with the source file that contains the declaration and initialization for the variable named testHeader
Compile these with the following command and you should see a linker error that complains saying that you have multiple definitions for the constructor
g++ -std=c++14 TestHeader.cpp yourfile.cpp
After you see those errors, remove the multiple definitions, either put all your definitions in the cpp file or only put them in one place and then recompile and link with the above command. The linker error should be gone.

C++ linker warning because of virtual destructor / clang

I'm getting a linker warning caused by virtual destructors. My environment is the KEIL compiler v6.5 (clang).
Warning: L6439W: Multiply defined Global Symbol __clang_call_terminate defined in invalid_group(new.cpp.o) rejected in favor of Symbol defined in .text.__clang_call_terminate(cxa_handlers.cpp.o).
I get this warning as soon as I add the virtual destructor to an interface. For example:
class IInterface {
virtual ~IInterface(){}
virtual void doSomething() const = 0;
}
As soon as I implement one single derived class of this interface I get the above mentioned warning. As soon as I remove the virtual destructor, the warning vanishes.
I tried really many things to find out what's the reason, but didn't succeed...
Does someone know how to fix this warning?
Thank you!
Edit: A complete example throwing this warning:
class IInterface {
public:
virtual ~IInterface();
virtual void doSomething() = 0;
};
IInterface::~IInterface() {
}
class SomeClass : public IInterface {
public:
virtual void doSomething();
};
void SomeClass::doSomething() {
}
int main() {
}
I asked support of ARM and got the information that this warning is spurious. So it seems to be an issue of the current ARM clang compiler toolchain implementation.
Nevertheless thank you all for your responses on this topic.
If you define your function in header you will emit the function each time you include it in a file. To remove this warming you need to define your method outside the declaration
// IInterface.hpp
class IInterface {
public:
virtual ~IInterface();
}
// IInterface.cpp
IInterface::~IInterface() {}
As mentioned, this was a linker bug which has been fixed in ARM Compiler v6.11 (10/25/2018).
Release notes:
[SDCOMP-30157] In certain circumstances, after discarding a section from a COMDAT ELF section group, the linker could incorrectly report Warning: L6439W: Multiply defined Global Symbol defined in invalid_group() rejected in favour of Symbol defined in (). This has been fixed.

C++ How to ignore defined method in header file?

i want a compiler (MinGW g++/Linux g++) to ignore some defined stuff in a header file:
class A {
public:
A();
virtual ~A();
IGNORE void methodA(); // = 0 -> not possible
IGNORE void methodB(); // = 0 -> not possible
}
The problem: methodA() and methodB() can't be pure virtual because the class would be later instanciated, so it gives a compiler error. The reason for doing that: i want to have a readable header file, so this methods should be appear in files - the methods are only used as in the QT framework to work as "signals", which are translated as Strings with a macro.
May be it is possible to declare a macro to let it be as annotation? i saw this in the QT5 framework (declared signal methods) but its not working with my code...
What i not want to do: list the methods only as DOC annotation.
Thanks for a idea how to solve that ;)
void methodA(int) = delete; // note: requires C++11
void methodA(double);
will cause a compiler error if you ever try to use methodA(int), but not if you're trying to use methodA(double).
Found a way to ignore methods as described what i want to do:
#define IGNORE __attribute__((unused))
#define METHOD_TO_STRING(a) ""#a
so i can write in header files
class A {
public:
IGNORE void methodA();
void doStuff(const char *stuff);
void methodB() {
doStuff(METHOD_TO_STRING(methodA());
}
};
Now the compiler is happy and i can pass methods as args :)
Thanks for the tips

undefined reference to vtable - virtual member, classes generated by gsoap

gsoap with its tools wsdl2h and soapcpp2 provided me with a soapStub.h file containing the following:
class SOAP_CMAC ns2__SOAPKunden
{
public:
std::string *adresszusatz;
// ...
public:
virtual int soap_type() const { return 7; }
// ...
ns2__SOAPKunden() : adresszusatz(NULL), x(NULL) { } // left out all member init.
virtual ~ns2__SOAPKunden() { }
};
I start with a small app using the class to populate objects with data from informix DB.
But to compile successfully i have to leave away all the virtual stuff - i found many postings about this error and use of virtual members in subclasses - otherwise i get
main.o: In function `ns2__SOAPKunden::ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenC1Ev[ns2__SOAPKunden::ns2__SOAPKunden()]+0xf): undefined reference to `vtable for ns2__SOAPKunden'
main.o: In function `ns2__SOAPKunden::~ns2__SOAPKunden()':
main.cpp:(.text._ZN15ns2__SOAPKundenD1Ev[ns2__SOAPKunden::~ns2__SOAPKunden()]+0x13): undefined reference to `vtable for ns2__SOAPKunden'
collect2: ld returned 1 exit status
I admit after years of scripting only it's very hard for me to make sense of C++ code... I want to ask for any advice what to try next. My class is no derived class, is for example what makes me wonder.
The error means that the virtual table has not been correctly compiled/linked in the final binary (executable or library). There are two common circumstances that lead to this error:
you are not linking the object file that includes the virtual table definitions --i.e. you compiled soapStub.cpp into soapStub.o, but did not add that binary to the linker command line.
the compiler is not generating the virtual table anywhere, so even if you are including all object files, that does not include the virtual table.
The second case is the hardest to identify for non-experienced developers, and can be caused by a class that is defined in the header and contains virtual functions. If all the virtual functions are defined inlined, the compiler will generate the virtual table in all translation units that include the header, and mark it as a weak symbol so that the linker can discard them, but if you later add a new virtual method and you leave it undefined in the header --or if you remove the definition from one of the virtual functions--, then the compiler will not generate the virtual table in each translation unit, but only in the one that defines those functions.
Things to check:
you are linking all object files
either all virtual functions are defined inline in the class definition or you have a .cpp that defines the virtual functions and you are linking that in.
This is what David Rodriguez said, just stated simpler I guess...
I had this situation in my interface class:
class IBase
{
public:
virtual void begin(unsigned long);
virtual void end();
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
and changed it to this:
class IBase
{
public:
virtual void begin(unsigned long) = 0;
virtual void end() = 0;
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
}
which did the trick.
begin() and end() were defined in derived class in a different file, IBase class (interface) was only declared in header and included in few places.
Error from OP only appeared when I set optimizations to none (-O0), any other setting resulted in no error (gcc 4.8).

GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'

I'm setting up a C++ project, on Ubuntu x64, using Eclipse-CDT. I'm basically doing a hello world and linking to a commerical 3rd party library.
I've included the header files, linked to their libraries, but I still get linker errors. Are there some possible problems here other than the obvious (e.g. I am 99% sure I'm linking to the correct library).
Is there a way to confirm the static libraries I am linking to are 64bit?
Is there a way to confirm that the library has the class (and methods) I am expecting it to have?
Eclipse says:
Building target: LinkProblem
Invoking: GCC C++ Linker
g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3
./src/LinkProblem.o: In function `main':
/home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()'
./src/LinkProblem.o: In function `SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()'
./src/LinkProblem.o: In function `~SomeOtherClass':
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'
collect2: ld returned 1 exit status
make: *** [LinkProblem] Error 1
This linker error usually (in my experience) means that you've overridden a virtual function in a child class with a declaration, but haven't given a definition for the method. For example:
class Base
{
virtual void f() = 0;
}
class Derived : public Base
{
void f();
}
But you haven't given the definition of f. When you use the class, you get the linker error. Much like a normal linker error, it's because the compiler knew what you were talking about, but the linker couldn't find the definition. It's just got a very difficult to understand message.
Assuming those methods are in one of the libs it looks like an ordering problem.
When linking libraries into an executable they are done in the order they are declared.
Also the linker will only take the methods/functions required to resolve currently outstanding dependencies. If a subsequent library then uses methods/functions that were not originally required by the objects you will have missing dependencies.
How it works:
Take all the object files and combine them into an executable
Resolve any dependencies among object files.
For-each library in order:
Check unresolved dependencies and see if the lib resolves them.
If so load required part into the executable.
Example:
Objects requires:
Open
Close
BatchRead
BatchWrite
Lib 1 provides:
Open
Close
read
write
Lib 2 provides
BatchRead (but uses lib1:read)
BatchWrite (but uses lib1:write)
If linked like this:
gcc -o plop plop.o -l1 -l2
Then the linker will fail to resolve the read and write symbols.
But if I link the application like this:
gcc -o plop plop.o -l2 -l1
Then it will link correctly. As l2 resolves the BatchRead and BatchWrite dependencies but also adds two new ones (read and write). When we link with l1 next all four dependencies are resolved.
Qt C++ will show this error when you change a class such that it now inherits from QObject (ie so that it can now use signals/slots). Running qmake -r will call moc and fix this problem.
If you are working with others via some sort of version control, you will want to make some change to your .pro file (ie add/remove a blank line). When everyone else gets your changes and runs make, make will see that the .pro file has changed and automatically run qmake. This will save your teammates from repeating your frustration.
The problem for me turned out to be pretty obscure. My class looked like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() { }
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
//-----------------------------------------
//-----------------------------------------
// main.h
class derived : public base {
public:
virtual int foo() ;
};
//-----------------------------------------
//-----------------------------------------
// main.cpp
int main () {
derived d;
}
//-----------------------------------------
The problem is in the linker. My header file went in a library somewhere, but all the virtual functions were declared 'inline' in the class declaration. Since there was no code using the virtual functions (yet), the compiler or linker neglected to put actual function bodies in place. It also failed to create the vtable.
In my main code where I derived from this class, the linker tried to connect my class to the base class and his vtable. But the vtable had been discarded.
The solution was to declare at least one of the virtual functions' bodies outside the class declaration, like this:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() ; //-- No longer declared 'inline'
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
base::~base()
{
}
//-----------------------------------------
In regards to problems with Qt4, I couldn't use the qmake moc option mentioned above. But that wasn't the problem anyway. I had the following code in the class definition:
class ScreenWidget : public QGLWidget
{
Q_OBJECT // must include this if you use Qt signals/slots
...
};
I had to remove the line "Q_OBJECT" because I had no signals or slots defined.
I had this error message. The problem was that I declared a virtual destructor in the header fileļ¼Œ but the virtual functions' body was actually not implemented.
This error will also occur when we simply declare a virtual function without any definition in the base class.
For example:
class Base
{
virtual void method1(); // throws undefined reference error.
}
Change the above declaration to the below one, it will work fine.
class Base
{
virtual void method1()
{
}
}
In my case the problem occured when i forgot to add the =0 on one function in my pure virtual class. It was fixed when the =0 was added. The same as for Frank above.
class ISettings
{
public:
virtual ~ISettings() {};
virtual void OKFunction() =0;
virtual void ProblemFunction(); // missing =0
};
class Settings : ISettings
{
virtual ~Settings() {};
void OKFunction();
void ProblemFunction();
};
void Settings::OKFunction()
{
//stuff
}
void Settings::ProblemFunction()
{
//stuff
}
I stumbled across the issue now, too. The application defined a pure virtual interface class and a user-defined class provided through a shared lib was supposed to implement the interface. When linking the application, the linker complained that the shared lib would not provide vtable and type_info for the base class, nor could they be found anywhere else.
Turned out that I simply forgot to make one of the interface's methods pure virtual (i.e. omitted the " = 0" at the end of the declaration. Very rudimentary, still easy to overlook and puzzling if you can't connect the linker diagnostic to the root cause.
I had this error message when trying "hello world" like things with Qt. The problems went away by correctly running the qt moc (meta object compiler) and compiling+including these moc-generated files correctly.
If you have a base class with pure virtual function, make sure your base class constructor and destructor has body otherwise linker fails.
I put this for future visitors:
if you are receiving the error on creating an Exception object, then the cause of it probably is a lack of definition for what() virtual function.