symbol not found AKA undefined symbol symbol not found AKA undefined symbol unix unix

symbol not found AKA undefined symbol


The error is not related to UNIX/Windows/any other OS, but rather to the languages themselves. It is actually rather simple to diagnose with the information that compilers provide. Usually they will tell you what symbol is missing and sometimes where it is being used. The main reasons for a symbol to be missing are:

  • You have declared but never defined it
  • You have defined it, but did not add the compiled symbol (object file/library) to the linker
  • It is external and you forgot to link the library, or you are linking an invalid version, or in the wrong order.

The first one is a little trickier if you intended to define the symbol but did not match the declaration (declared void foo( int, double );, but defined void foo( double, int ). As with all other cases, the compiler will tell you the exact signature that it is looking for, make sure that you have defined that symbol, and not something close or similar, a particular corner case can be if you are using different calling conventions in the declaration and the definition, as they will look very similar in code.

In the case of libraries external code the complexity is in identifying what library needs to be linked for that symbol to be added, and that comes from the documentation of the lib. Beware that with static libraries the order of the libs in the linker command line affects the result.

To help you in finding what symbols are actually defined you can use nm (gcc, which is common among unix systems). So basically you can run nm against the object files/libs that you are linking and search for the symbol that the linker is complaining about. This will help in cases where the order is what makes the difference (i.e. the symbol is there, but the linker skipped it).

At runtime (thanks to Matthieu M. for pointing it out) you might have similar issues with dynamic libraries, if the wrong version of a library is found in the LD_LIBRARY_PATH you might end up with a library that does not have a required symbol.


Although they can be platform dependent, I have some "more complex" instances of some of the points from Andreas and David:

  • When dealing with shared libraries (.so or.dll) and linking against symbols which are not exported (dllimport/dllexport on Windows and visibility("default") with GCC on *nix)
  • Or similar: Linking against the static lib, while expecting a shared lib or vice versa. This one is bit similar to Mathieu's comment about linking against another, unexpected version of the library.
  • Creating a pure virtual classs and not providing an implementation for at least one method (causing no vtable to be available).
  • Actually a more complex case of declaring but not defining: The linking errors you can get when dealing with large, nested templates. Finding out what was not defined can be difficult with large error messages.


For most cases when you get a symbol not found/undefined symbol or sometimes even a "duplicate symbol" error, they usually stem from the fact that the linker is unable to find the symbol in the project that you are trying to build.

The best way to go about it is to look at the map file generated or a symbol table that is the output of the compiler. It may look something like this:

Symbols

This will allow you to see if the symbol is present or not. Also, there might be other esoteric problems such as compiler optimizations that might cause a symbol duplication especially with inline assembly. These are about the hardest to detect.

As for good resources and materials, I don't have many good references. When I did ask around back then, most of the senior engineers have actually learned from their own experiences.

But I'm sure that's where forums such as these are present to help us expedite such knowledge acquisition.

Hope it helped :)

Cheers!