The information in this article applies to:
SUMMARY
The linker issues an Unresolved External message if it cannot resolve the
address of a function while building a project.
With the 32-bit version of Visual C++ version 1.0, this message is: With the 32-bit version of Visual C++ version 2.0 and later, this message is: The '__symbol' might be a label, a variable, or a function name. This article discusses some of the most common causes of this error to help you troubleshoot it. MORE INFORMATION
The following explanation of linker behavior explains why this error
occurs. This is a simplified model, and the internal implementation may
vary slightly between compiler versions; however, the information is
sufficient for trying to find the cause of this error message.
Figure 1
The linker uses the PST and UST of a project's object and library files to
match symbol names. If the linker finds a symbol in a UST table and cannot
find a matching entry in one of the many PST tables, it issues an
"Unresolved External" error message. For example, in Figure 1, the linker
cannot resolve the address for the function func3() and therefore issues an
"Unresolved External" error.
Frequent Causes of the "Unresolved External" Error MessageThe remainder of this article discusses in detail each of the following possible causes of "Unresolved External" errors:
Missing Object Files or LibrariesIf a needed object module or library is not included on the link command line, the linker may not be able to find addresses for one or more symbols, so it issues an unresolved external error message. You need to place the necessary library or object file in the project.The names of the C Run-Time libraries needed at link time are included in the object module by the compiler. For 32-bit versions of Visual C++, the MFC libraries are also included. If you use the /NOD (/NODEFAULTLIB) linker switch, these libraries will not be linked into the project unless you have explicitly included them. The same problem occurs if you use the /NOD:<libraryname> switch to prevent specific libraries from being linked in. If the unresolved external is a C Run-Time library function, then you need to specify the Run-Time library to the linker. Starting with Visual C++ version 4.0, the libraries containing the C Run-Time function are listed in the online help for the function. With Visual C++ version 4.0, the library containing each Windows API function is listed under the QuickInfo link in the online help for each function. For 32-bit versions of Visual C++, a list of the libraries containing each Windows API function is in the Win32api.csv file located in the \Lib subdirectory. This is a comma-separated variable file that can be loaded into a spreadsheet for easy viewing. It can also be viewed with a text editor. Note that there is no similar file for the 16-bit Windows API functions. A DLL should provide a .lib or .def file that allows the linker to resolve references to the DLL functions unless you are using explicit LoadLibrary()and GetProcAddress() calls in your code. With the 16-bit linker, using over 32 libraries will cause problems as the 33rd library will be ignored. For more information, please see the following article in the Microsoft Knowledge Base: Q31986 Maximum Number of Libraries LINK Supports Missing Function Body or VariableIf just a function prototype is provided, the linker will not be able to resolve any function calls because there is no function definition. As a result, the function is not listed in the combined PST table. Similarly, if an external variable is declared but not defined, the same problem occurs.For example:
When using C++, make sure you provide a function definition for each
function in a class and not just a prototype in the class definition. If
you are defining the function outside of the class definition, be sure to
include the class name before the function in the Classname::MemberFunction
style. See the "Scoping Problems and Pure Virtual Functions" section for an
example.
Symbol Can't Be Found in the Libraries or Object ModulesUse Dumpbin.exe or Lib.exe to find out if the symbol is in the object module or library.With 32-bit COFF object modules and libraries, you can verify whether a symbol is in the file with Dumpbin.exe. For object modules, use this command:
For libraries, use this command:
For 16-bit libraries, use Lib.exe to view the symbols defined in the
library. To create a listing use this command:
If you want to determine what symbols are contained in an object module,
create a dummy library and listing file from the object module with
Lib.exe. For example:
On Windows 95, you can use the QuickViewer to see some of this same
information for .exe and .dll files.
Some functions can only be used in certain environments so they are not in every library. To determine what environment a Run-Time function can be used in, check the compatibility in the online documentation. Not every compiler vendor offers the same libraries of functions. Microsoft offers all the ANSI standard functions for C plus many others. Microsoft may offer functions other companies do not, and vice-versa. Similarly, mixing versions of Microsoft libraries and compiler products can be problematic. Each released product is tested only with components included in that release, unless otherwise stated in the documentation or release notes. A new compiler version's libraries may contain new symbols that cannot be found in the libraries included with previous versions. Case SensitivityCase is important when linking function references in each object module's UST to the references in the PSTs. The only exception is if you are doing all three of the following:
Name DecorationUsually "name decoration" refers to C++ naming conventions, but it applies to a number of non-C++ cases as well. The compiler may use the name of a function, its parameters, and its return type when calculating a name for a function. For example, with Visual C++ 2.0, the function name for
might come to anything in the following table depending on what the
CALLTYPE is and whether it is a C or a C++ file.
CALLTYPEs such as _cdecl, _fastcall, and _stdcall change the naming
conventions for a function or variable. The 32-bit specific
__declspec(<attribute>) modifier can also affect the name of the function.
If using C++, be sure to use extern "C" if you are calling a C function from a C++ program or if you are calling a function in a C++ from a C program. Extern "C" forces use of the C naming convention for global C++ functions; this enables them to be called from a C program. Be aware of compiler switches like /Tp or /Tc that force a file to be compiled as a C (/Tc) or C++ (/Tp) file regardless of the filename extension, or you may get different function names than you expected. Function prototypes with mismatched parameters can also cause unresolved external errors. Many name-decoration schemes incorporate the parameters of a function into the final decorated function name. Calling a function with parameter types that do not match those in the function definition may also cause this error. This can be a problem in other languages, like FORTRAN, which may also add name decoration to a function. In the following example, the header file with the function prototype does not match the function definition; this causes the problem. Example:
There is no set standard for naming conventions between compiler vendors or
even between different versions of a compiler. Therefore cross-linking
object files compiled with other compilers or compiler versions may cause
unresolved externals.
A Symbol Is Not PublicOnly global functions and variables are placed in the object file's PST table. Trying to access variables of the types below may cause Unresolved Externals.Static functions/variables: "Static" functions and variables have file scope. Trying to access static symbols from outside of the file they are defined in will cause an unresolved external. For example:
Automatic (function scope) variables:
A variable declared within a function can only be used within the scope of that function. For example:
Global Constants in C++:
C++ global constants have static linkage. This is different from C. If you try to use a global constant in C++ in multiple files, you get an unresolved external error. The following code illustrates this error:
One alternative is to include the const initializations in a header file,
and include that header in your C++ files when necessary, just as if it was
a function prototype. Another possibility is to make the variable non-
constant and use a const reference when accessing it.
Global Inline Functions in C++: Global inline functions have static or internal linkage. They cannot be called from functions in other modules. See the "Function Inlining" section for further information on function inlining. Scoping Problems and Pure Virtual FunctionsA common cause of scoping problems is incorrectly included prototypes that cause the compiler to expect a function body that is not provided.A::F() or F(): Sometimes a call to a function F() may map to a class implementation, class A::F(), instead of a global implementation of F() because C++ implicitly links with class implementations when resolving function calls inside other class function bodies. Alternatively, if you defined the C++ implementation of a class member function A::F() outside of the class declaration itself, you must explicitly include the class name in the function definition. Both of these cases can cause confusion if you have both a class and a global implementation of a function F(). For example:
This case could be wrong in one of two ways. The function call in
PublicStatMemFunc1() should have the scope resolution operator (::) added
to make a call to ::F(). The compiler will then know that the user meant to
call a global function. Alternatively, if the user meant F() to be the
class implementation of F(), the definition needs to be changed to A::F().
Abstract Base classes: Attempting to call a pure virtual C++ function from the constructor or destructor of an abstract base class also causes this problem. This is because by definition, a pure virtual function should have no base class implementation. The following example illustrates this situation:
Function InliningMixing inline and non-inline compile options on different modules can cause problems. Consider the following example that has:
Similarly, a project that uses function inlining yet defines the functions in a source file rather than in the header file will also get this error. The header file is included everywhere deemed appropriate, but the functions are only inlined in the source file where they are defined. Therefore, the linker sees the functions as unresolved externals when used in other modules. For example:
For more information on inline functions and unresolved externals, please
see the following article in the Microsoft Knowledge Base:
Q123768 Unresolved Externals for Inline FunctionsWhen inlining, if you are using the #pragma inline_depth compiler directive, make sure you have set a value of one or greater. A value of zero will turn off inlining. Also use the /Ob1 or /Ob2 compiler switches. These switches allow the compiler to inline functions. To set these options in 32-bit Visual C++ version 4.0, on the Build menu, click Settings, and then switch to the C/C++ tab, and choose Optimizations. For 16-bit Visual C++, on the Options menu, click Project, and then click Compiler, and change the Category to Optimizations. NOTE: You can't force the compiler to inline anything. You can only suggest functions that would be suitable for inlining with the options mentioned above. Wrong Compiler Options or Mixing Incompatible LibrariesCertain compiler options have implications with respect to the library that should be used at link time. The following table shows the relationship for Visual C++ version 2.x. The compiler will include the name of the library you should link to in the object file. Using the /NODEFAULTLIB switch will cause the compiler to ignore these references, so you need to make sure that you link with the correct libraries.
For more information on these options, please see the following article in
the Microsoft Knowledge Base:
Q128641 The /Mx Compiler Options and the LIBC, LIBCMT, MSVCRT LibsMsvcrt.lib will link with a different version of the run time depending on the version of Visual C++ that you are using. For version 2.x, the DLL is Msvcrt20.dll. Also, note that with Visual C++ version 2.x, there are two versions of Msvcrt20.dll -- one that targets Windows NT and Windows 95 and one that targets Win32s. For more information on these DLLs, please see the following article in the Microsoft Knowledge Base: Q125476 PRB Error "...MSVCRT20.DLL is not compatible with Win32s"Libc.lib, Libcmt.lib, and Msvcrt.lib and their corresponding compile options are mutually exclusive for one project. Only one switch and its corresponding library should be used for compiling and linking all of the modules in a project. The following are some cases where these options can cause unresolved externals:
REFERENCESSearch in the Microsoft Knowledge Base using L2029 for a list of articles that describe the problems you may encounter with the 16-bit version of Visual C++. For the 32-bit versions, search using LNK2001 or LNK4016.
Keywords : LinkIss |
Last Reviewed: July 9, 1999 © 2000 Microsoft Corporation. All rights reserved. Terms of Use. |