cpp

When your C++ code complains about undefined references

tenry

Tenry

Posted on December 9, 2020

When your C++ code complains about undefined references

Usually, when you compile and link your code and your compiler complains about undefined references, you check which references are missing and usually quickly find out which library you forgot to link.

Today, however, I encountered a strange issue where the compiler complained even though the (static) library, which provides the symbols in question, was clearly added to the command line that links the final binary. So what was going on?

In my specific case, I built the Lua library, and got some files in the end, including some header files like lua.h or lauxlib.h and of course the liblua.a. I wrote some basic code to verify that Lua is actually working. Following some quickstart tutorial on the internet, my C++ code somewhat looked like this:

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

int main(int argc, char **argv) {
  lua_State *L;
  L = luaL_newstate();
  luaopen_base(L);

  luaL_loadstring(L, "(some lua code)");

  // and so on...

  return 0;
}
Enter fullscreen mode Exit fullscreen mode

I put everything in a CMake file, compiled and bam, undefined references. I enabled verbose output to verify it's actually linking the liblua.a file. I verified it's the right location and the file actually exist.

Didn't I compile the Lua library correctly? Were the symbols in question missing? Using nm showed me that the symbols in questions are there:

$ nm liblua.a | grep luaL_loadstring
0000000000002d60 T luaL_loadstring
Enter fullscreen mode Exit fullscreen mode

So, why does it complain? It took like like half an hour to figure out where the issue is.

The solution

The issue is C++. C++ uses name mangling which differs from the generated names in C. Lua is a C library and I compiled it as C. Since I include the C header file lua.h in a C++ file, it's treated as C++ code, hence the compiler is looking for C++ names.

Luckily, Lua also provides a C++ header file, lua.hpp. I replaced my #include <lua.h> by #include <lua.hpp> and et voilà, it works!

What does lua.hpp actually do? Not much:

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
Enter fullscreen mode Exit fullscreen mode

If you have some experience with coding in C++, you might already have used other C libs, also simply #include <somelib.h>, without having any issues. So, what do others do? Checking the C header file of another lib, the outline looks like this:

#ifdef __cplusplus
extern "C" {
#endif

// all the declarations go here

#ifdef __cplusplus
}
#endif
Enter fullscreen mode Exit fullscreen mode

__cplusplus is only defined if this file is processed as a C++ file. For some reason, the lua.h file does not do that, so that's why they provided a dedicated C++ header file.

💖 💪 🙅 🚩
tenry
Tenry

Posted on December 9, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Jas - My x64 assembler
assembly Jas - My x64 assembler

November 30, 2024

Python C/C++ binding
undefined Python C/C++ binding

November 27, 2024

DocWire new release 2024.11.23
cpp DocWire new release 2024.11.23

November 25, 2024