Gcc C++ Linker Errors: Undefined Reference to 'Vtable For Xxx', Undefined Reference to 'Classname::Classname()'

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.

  1. Put the underscore after the variable name. As names that start with
    an underscore may be used by the compiler.
  2. Make sure to define at least one virtual function if you plan on
    inheriting from it or using RTTI. (ex. a Virtual Destructor)
  3. 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



Leave a reply



Submit