Recent Posts

A Comprehensive Guide to Unresolved External Symbols in C++

 Consider you have this piece of code:

 

 

During the compilation of b.cpp, the compiler treats the get() symbol as an external reference, deferring its resolution. The linker is subsequently responsible for locating the symbol's definition and unifying the object files generated from a.cpp and b.cpp.

If a.cpp didn't define get, you would get a linker error saying "undefined reference" or "unresolved external symbol".

 In accordance with C++ Standard terminology, the compilation process is partitioned into various translation phases. The concluding phase is the one that directly applies here:

All external entity references are resolved. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment. 

 These errors surface during the final stage of the build process, known as linking. At this point, the compiler has already turned your individual source files into object files or libraries; the linker’s job is to "stitch" them together so they can function as a single program.

 Linking in the Wild: Visual Studio & Beyond

In Microsoft Visual Studio, projects typically produce .lib files. Think of these as catalogs containing two specific lists:

  • Exported symbols: The functions or variables this library provides to others.

  • Imported symbols: The "missing pieces" this library needs from elsewhere to work.

The linker looks at these tables and matches the imports of one file to the exports of another. While the terminology might change slightly, this same fundamental "handshake" happens across almost all compilers and platforms.

 Common Linker Error Messages

If the linker can't find a definition for one of those imported symbols, it will throw an error. Here is what that looks like depending on your environment: 

EnvironmentTypical Error Codes / Messages
MS Visual Studioerror LNK2001, error LNK2019, error LNK1120
GCC / Clangundefined reference to 'symbolName'

Essentially, the compiler is saying: "I know you want to use this function, but I can't find the actual code for it anywhere." 


struct X
{
   virtual void foo();
};
struct Y : X
{
   void foo() {}
};
struct A
{
   virtual ~A() = 0;
};
struct B: A
{
   virtual ~B(){}
};
extern int x;
void foo();
int main()
{
   x = 0;
   foo();
   Y y;
   B b;
}


will generate the following errors with GCC:


1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ)
1>...\test2.exe : fatal error LNK1120: 4 unresolved externals

No comments:

Post a Comment