GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'
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.
Linking error: undefined reference to `vtable for XXX`
You never provided an implementation for virtual ~Interval();
and several other functions. You must provide an implementation for all non-pure virtual functions you declare. In particular, G++ emits the vtable along with the implementation of the first-declared non-inline function in a class. Omitting its implementation means you won't have a vtable, and thus won't be able to construct the class (hence these errors).
In short, define every function you declare, except for pure virtuals. There are some cases where it's justified to leave out the definition for a declared function, but they are very rare.
ERROR : undefined reference to classname::member_variable
static int a;
This declares the static variable. That tells the compiler that this field exists and would be of type int
. This is useful information for compiling the code.
But the variable still needs to be defined. That is some translation unit(and exactly one translation unit) needs to allocate the memory for this variable. See What is a "translation unit" in C++
For other NITs of declaration and definition check this question: What is the difference between a definition and a declaration?
As to the solution you need to add a definition as well outside the class:
int Demo_StaticVar::a;
int main(){
...
Code link: https://ideone.com/l7ie7p
How do I resolve the undefined reference to `vtable for <<ClassName>> error?
I see a declaration for ~Manager()
but I don't see a definition. This needs to be in Manager.cpp.
I believe you are getting this obscure message because the vtable
holds the addresses of all virtual functions. You only have one virtual function and you haven't defined it.
I can't reproduce the vector
error. Once I add ~Manager::Manager() { }
to Manager.cpp
, my version compiles fine.
undefined reference to 'vtable for classname'
A couple of things.
- Put the underscore after the variable name. As names that start with
an underscore may be used by the compiler. - Make sure to define at least one virtual function if you plan on
inheriting from it or using RTTI. (ex. a Virtual Destructor) - Make sure that every declared function has a corresponding
implementation.
Why does the compiler throw undefined reference to ... despite providing all needed libraries in the arguments
Please try this instead. The sequence of arguments you provided to g++ actually matters. Always put the library at the end of your arguments.
g++ -o test.exe test.cpp -lkernel32 -lpsapi
The g++ tool chain will first go through test.cpp
and compile it to a binary object file, which is a temporary file having a funny name, but let us call it test.o
for now. At this time, there are still some function references in test.o
which cannot be resolved.
Then, the g++ tool chain sees -lkernel32
and then -lpsapi
. It goes in these two libraries in sequence and find those missing functions in test.o
for you.
If you are linking statically, it will copy the compiled binary code of the functions in need from the library and splice it to test.o
. If you are linking dynamically, it will set up some "entry" to the dynamic library.
This is what makes the sequence to be important. The compiler tool chain will only copy (set up entry) those function in need, since a library is typically very large and contains many other functions you don't really need. When currently nothing is needed from the libraries, like the command you originally wrote, g++ needs nothing from -lkernel32 -lpsapi
before running into test.cpp
, it will simply skip those libraries.
In short, if lib_a
depends on lib_b
, you should put lib_a
before lib_b
in the arguments. In rare cases where lib_x
depends on lib_y
which in turn depends on lib_x
, you must write something like g++ file.cpp lib_x lib_y lib_x
.
Note that this rule only applies to libraries. All functions in the source file will be kept in the binary object file. Thus, even if file_x
depends on file_y
, writing g++ file_y.cpp file_x.cpp
is okay, since all functions are kept in file_y.o
and file_x.o
, when linking them together, the linker can find them.
Related question: GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()'
Building Qt app with CONFIG += staticlib causes undefined reference to vtable errors
The answer is disappointingly simple: the libraries were linked in the wrong order.
I looked at the command that invoked the linker (right above the linker error):
g++ [...] -lStadium [...] -lFootball
I also looked into the code: The Football subproject refers to the Stadium subproject, so the libraries are in the wrong order, see for example the accepted answer of GCC C++ Linker errors: Undefined reference to 'vtable for XXX', Undefined reference to 'ClassName::ClassName()' for explanation.
Indeed, if I swap the two libraries in the Server.pro file (derived from commit 09836f9
, irrelevant win32 specific details deleted for brevity):
[...]
SOURCES += main.cpp
LIBS += -L$$OUT_PWD/../Football/ -lFootball
INCLUDEPATH += $$PWD/../Football
DEPENDPATH += $$PWD/../Football
PRE_TARGETDEPS += $$OUT_PWD/../Football/libFootball.a
LIBS += -L$$OUT_PWD/../Stadium/ -lStadium
INCLUDEPATH += $$PWD/../Stadium
DEPENDPATH += $$PWD/../Stadium
PRE_TARGETDEPS += $$OUT_PWD/../Stadium/libStadium.a
Now the command line looks like:
g++ [...] -lFootball [...] -lStadium
It compiles and runs just fine on my Linux machine.
Related Topics
What Are Some Uses of Decltype(Auto)
Where Exactly Does C++ Standard Say Dereferencing an Uninitialized Pointer Is Undefined Behavior
The Procedure Entry Point _Gxx_Personality_V0 Could Not Be Located
Writing Bmp Image in Pure C/C++ Without Other Libraries
How to Get the Index of an Iterator of an Std::Vector
How to Match Multiple Results Using Std::Regex
If (Cin ≫≫ X) - Why Can You Use That Condition
Why Is the Template Argument Deduction Not Working Here
How to Find If a Given Key Exists in a C++ Std::Map
How to Get Rid of 'Deprecated Conversion from String Constant to 'Char*'' Warnings in Gcc
Examples of When a Bitwise Swap() Is a Bad Idea
A Std::Map That Keep Track of the Order of Insertion
Std::Vector Versus Std::Array in C++
How to Change Mode from C++98 Mode in Dev-C++ to a Mode That Supports C++0X (Range Based For)
Does Std::String Have a Null Terminator
Atomic Double Floating Point or Sse/Avx Vector Load/Store on X86_64