What are undefined reference/unresolved external symbol errors? What are common causes and how to fix/prevent them?
Feel free to edit/add your own.
Compiling a C++ program takes place in several steps, as specified by 2.2 (credits to Keith Thompson for the reference):
The specified errors occur during this last stage of compilation, most commonly referred to as linking. It basically means that you compiled a bunch of implementation files into object files or libraries and now you want to get them to work together.
Say you defined symbol
If you're using Microsoft Visual Studio, you'll see that projects generate
Similar mechanisms exist for other compilers/ platforms.
Common error messages are
will generate the following errors with GCC:
and similar errors with Microsoft Visual Studio:
Common causes include:
Failure to link against appropriate libraries/object files or compile implementation files
Commonly, each translation unit will generate an object file that contains the definitions of the symbols defined in that translation unit. To use those symbols, you have to link against those object files.
Under gcc you would specify all object files that are to be linked together in the command line, or compile the implementation files together.
For XCode: Add the User Header Search Paths -> add the Library Search Path -> drag and drop the actual library reference into the project folder.
Under MSVS, files added to a project automatically have their object files linked together and a
It can also happen that you forget to add the file to the compilation, in which case the object file won't be generated. In gcc you'd add the files to the command line. In MSVS adding the file to the project will make it compile it automatically (albeit files can, manually, be individually excluded from the build).
In Windows programming, the tell-tale sign that you did not link a necessary library is that the name of the unresolved symbol begins with
Declared but did not define a variable or function.
A typical variable declaration is
As this is only a declaration, a single definition is needed. A corresponding definition would be:
For example, the following would generate an error:
Similar remarks apply to functions. Declaring a function without defining it leads to the error:
Be careful that the function you implement exactly matches the one you declared. For example, you may have mismatched cv-qualifiers:
Other examples of mismatches include
The error message from the compiler will often give you the full declaration of the variable or function that was declared but never defined. Compare it closely to the definition you provided. Make sure every detail matches.
Template implementations not visible.
Unspecialized templates must have their definitions visible to all translation units that use them. That means you can't separate the definition of a template
to an implementation file. If you must separate the implementation, the usual workaround is to have an
To fix this, you must move the definition of
Specialized templates can be implemented in an implementation file and the implementation doesn't have to be visible, but the specialization must be previously declared.
For further explanation and another possible solution (explicit instantiation) see this question and answer.
Symbols were defined in a C program and used in C++ code.
The function (or variable)
The C++ linker expects names to be mangled, so you have to declare the function as:
Equivalently, instead of being defined in a C program, the function (or variable)
and you attempt to use it in a C++ program with C++ linkage.
If an entire library is included in a header file (and was compiled as C code); the include will need to be as follows;
Incorrectly importing/exporting methods/classes across modules/dll (compiler specific).
MSVS requires you to specify which symbols to export and import using
This dual functionality is usually obtained through the use of a macro:
and tells the compiler to export the function, as the current module contains its definition. When including the declaration in a different module, it would expand to
and tells the compiler that the definition is in one of the libraries you linked against (also see 1)).
You can similary import/export classes:
If all else fails, recompile.
I was recently able to get rid of an unresolved external error in Visual Studio 2012 just by recompiling the offending file. When I re-built, the error went away.
This usually happens when two (or more) libraries have a cyclic dependency. Library A attempts to use symbols in B.lib and library B attempts to use symbols from A.lib. Neither exist to start off with. When you attempt to compile A, the link step will fail because it can't find B.lib. A.lib will be generated, but no dll. You then compile B, which will succeed and generate B.lib. Re-compiling A will now work because B.lib is now found.
undefined reference to
You may have missed to choose the right project type with your actual IDE. The IDE may want to bind e.g. Windows Application projects to such entry point function (as specified in the missing reference above), instead of the commonly used
If your IDE supports Plain Console Projects you might want to choose this project type, instead of a windows application project.
Linked .lib file is associated to a .dll
I had the same issue. Say i have projects MyProject and TestProject. I had effectively linked the lib file for MyProject to the TestProject. However, this lib file was produced as the DLL for the MyProject was built. Also, I did not contain source code for all methods in the MyProject, but only access to the DLL's entry points.
To solve the issue, i built the MyProject as a LIB, and linked TestProject to this .lib file (i copy paste the generated .lib file into the TestProject folder). I can then build again MyProject as a DLL. It is compiling since the lib to which TestProject is linked does contain code for all methods in classes in MyProject.
Also if you're using 3rd party libraries make sure you have the correct 32/64 bit binaries
The order in which interdependent linked libraries are specified is wrong.
The order in which libraries are linked DOES matter if the libraries depend on each other. In general, if library
Create the libraries:
So to repeat again, the order DOES matter!
Microsoft offers a
In addition to the library path including the directory of the library, this should be the full name of the library.
what is an "undefined reference/unresolved external symbol"
I'll try to explain what is an "undefined reference/unresolved external symbol".
For example we have some code
Make object files
After the assembler phase we have an object file, which contains any symbols to export. Look at the symbols
I've rejected some lines from output, because they do not matter
So, we see follow symbols to export.
src2.cpp exports nothing and we have seen no its symbols
Link our object files
and run it
Linker sees exported symbols and links it. Now we try to uncomment lines in src2.cpp like here
and rebuild an object file
OK (no errors), because we only build object file, linking is not done yet. Try to link
It has happened because our local_var_name is static, i.e. it is not visible for other modules. Now more deeply. Get the translation phase output
So, we've seen there is no label for local_var_name, that's why linker hasn't found it. But we are hackers :) and we can fix it. Open src1.s in your text editor and change
i.e. you should have like below
we have changed the visibility of local_var_name and set its value to 456789. Try to build an object file from it
ok, see readelf output (symbols)
now local_var_name has Bind GLOBAL (was LOCAL)
and run it
ok, we hack it :)
So, as a result - an "undefined reference/unresolved external symbol error" happens when the linker cannot find global symbols in the object files.
A bug in the compiler/IDE
I recently had this problem, and it turned out it was a bug in Visual Studio Express 2013. I had to remove a source file from the project and re-add it to overcome the bug.
Steps to try if you believe it could be a bug in compiler/IDE:
Visual Studio NuGet package needs to be updated for new toolset version
I just had this problem trying to link libpng with Visual Studio 2013. The problem is that the package file only had libraries for Visual Studio 2010 and 2012.
The correct solution is to hope the developer releases an updated package and then upgrade, but it worked for me by hacking in an extra setting for VS2013, pointing at the VS2012 library files.
I edited the package (in the
A wrapper around GNU ld that doesn't support linker scripts
Some more complex builds may not support this. For example, if you include -v in the compiler options, you can see that the mainwin gcc wrapper mwdip discards linker script command files in the verbose output list of libraries to link in. A simple work around is to replace the linker script input command file with a copy of the file instead (or a symlink), e.g.
Or you could replace the -l argument with the full path of the .so, e.g. instead of
This is one of most confusing error messages that every VC++ programmers have seen time and time again. Let’s make things clarity first.
A. What is symbol? In short, a symbol is a name. It can be a variable name, a function name, a class name, a typedef name, or anything except those names and signs that belong to C++ language. It is user defined or introduced by a dependency library (another user-defined).
B. What is external?
In VC++, every source file (.cpp,.c,etc.) is considered as a translation unit, the compiler compiles one unit at a time, and generate one object file(.obj) for the current translation unit. (Note that every header file that this source file included will be preprocessed and will be considered as part of this translation unit)Everything within a translation unit is considered as internal, everything else is considered as external. In C++, you may reference an external symbol by using keywords like
C. What is “resolve”? Resolve is a linking-time term. In linking-time, linker attempts to find the external definition for every symbol in object files that cannot find its definition internally. The scope of this searching process including:
This searching process is called resolve.
D. Finally, why Unresolved External Symbol? If the linker cannot find the external definition for a symbol that has no definition internally, it reports an Unresolved External Symbol error.
E. Possible causes of LNK2019: Unresolved External Symbol error. We already know that this error is due to the linker failed to find the definition of external symbols, the possible causes can be sorted as:
For example, if we have a function called foo defined in a.cpp:
In b.cpp we want to call function foo, so we add
to declare function foo(), and call it in another function body, say
Now when you build this code you will get a LNK2019 error complaining that foo is an unresolved symbol. In this case, we know that foo() has its definition in a.cpp, but different from the one we are calling(different return value). This is the case that definition exists.
If we want to call some functions in a library, but the import library is not added into the additional dependency list (set from:
Use the linker to help diagnose the error
Most modern linkers include a verbose option that prints out to varying degrees;
For gcc and clang; you would typically add
Suppose you have a big project written in c++ which has a thousand of .cpp files and a thousand of .h files.And let's says the project also depends on ten static libraries. Let's says we are on Windows and we build our project in Visual Studio 20xx. When you press Ctrl + F7 Visual Studio to start compiling the whole solution ( suppose we have just one project in the solution )
What's the meaning of compilation ?
The Second step of compilation is done by Linker.Linker should merge all the object file and build finally the output ( which may be an executable or a library)
Steps In Linking a project
How To Solve this kind of error
Compiler Time Error :
Linker Time Error
Since people seem to be directed to this question when it comes to linker errors I am going to add this here.
One possible reason for linker errors with GCC 5.2.0 is that a new libstdc++ library ABI is now chosen by default.
So if you suddenly get linker errors when switching to a GCC after 5.1.0 this would be a thing to check out.
Clean and rebuild
A "clean" of the build can remove the "dead wood" that may be left lying around from previous builds, failed builds, incomplete builds and other build system related build issues.
In general the IDE or build will include some form of "clean" function, but this may not be correctly configured (e.g. in a manual makefile) or may fail (e.g. the intermediate or resultant binaries are read-only).
Once the "clean" has completed, verify that the "clean" has succeeded and all the generated intermediate file (e.g. an automated makefile) have been successfully removed.
This process can be seen as a final resort, but is often a good first step; especially if the code related to the error has recently been added (either locally or from the source repository).
Given the code snippet of a template type with a friend operator (or function);
Since it is not implemented, the linker fails to find it and results in the error.
To correct this, you can declare a template operator before the
The above code limits the friendship of the operator to the corresponding instantiation of
Note, when the declaration of the operator (or function) only appears in the class, the name is not available for "normal" lookup, only for argument dependent lookup, from cppreference;
As a side note to the failing code sample; g++ warns about this as follows
When your include paths are different
Linker errors can happen when a header file and its associated shared library (.lib file) go out of sync. Let me explain.
How do linkers work? The linker matches a function declaration (declared in the header) with its definition (in the shared library) by comparing their signatures. You can get a linker error if the linker doesn't find a function definition that matches perfectly.
Is it possible to still get a linker error even though the declaration and the definition seem to match? Yes! They might look the same in source code, but it really depends on what the compiler sees. Essentially you could end up with a situation like this:
Note how even though both the function declarations look identical in source code, but they are really different according to the compiler.
You might ask how one ends up in a situation like that? Include paths of course! If when compiling the shared library, the include path leads to
An example of how this can happen in the real world is explained below.
Further elaboration with an example
I have two projects:
And then you go ahead and include the library in your own project.
Boom! You get a linker error and you have no idea why it's failing. The reason is that the common library uses different versions of the same include
Note in this example, the linker would tell you it couldn't find
Debugging the linker
DUMPBIN is your friend, if you are using Visual Studio. I'm sure other compilers have other similar tools.
The process goes like this:
 By project I mean a set of source files that are linked together to produce either a library or an executable.
EDIT 1: Rewrote first section to be easier to understand. Please comment below to let me know if something else needs to be fixed. Thanks!
Your linkage consumes libraries before the object files that refer to them
Examples are in C. They could equally well be C++
A minimal example involving a static library you built yourself
You build your static library:
You compile your program:
You try to link it with
The same result if you compile and link in one step, like:
A minimal example involving a shared system library, the compression library
Missing "extern" in