Linker Tools Error LNK2019 

Error Message

unresolved external symbol 'symbol' referenced in function 'function'

An undefined external symbol (symbol) was found in function. To resolve this error, provide a definition for symbol or remove the code that references it. For more information, see,

The following sample generates LNK2019:

// LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B is not in avilable to the linker
int main() {
   B[0] = ' ';
}

LNK2019 can also occur when you declare but do not define a static data member. The following sample generates LNK2019:

// LNK2019b.cpp
// LNK2019 expected
struct C {
   static int s;
};

// Uncomment the following line to resolve.
// int C::s;

int main() {
   C c;
   C::s = 1;
}

Consider the following sample:

// LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

If i and g are not defined in one of the files included in the build, the linker will generate LNK2019. These definitions can be added by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass .obj or .lib files that contain the definitions to the linker.

For C++ projects from previous releases that were upgraded to the current version, if __UNICODE was defined and the entry point was WinMain, you need to change the name of the entry point function to either _tWinMain or _tmain.

Common problems that cause LNK2019 include:

  • The declaration of the symbol contains a spelling mistake, such that, it is not the same name as the definition of the symbol.

  • A function was used but the type or number of the parameters did not match the function definition.

  • The calling convention (__cdecl, __stdcall, or __fastcall) differs on the use of the function declaration and the function definition.

  • Symbol definitions are in a file that was compiled as a C program and symbols are declared in a C++ file without an extern "C" modifier. In that case, modify the declaration, for example, instead of:

    extern int i;
    extern void g();
    

    use:

    extern "C" int i;
    extern "C" void g();
    

    Similarly, if you define a symbol in a C++ file that will be used by a C program, use extern "C" in the definition.

  • A symbol is defined as static and then later referenced outside the file. In C++, unlike C, global constants have static linkage. To get around this limitation, you can include the const initializations in a header file and include that header in your .cpp files, or you can make the variable non-constant and use a constant reference to access it.

  • A static member of a class is not defined. For example, member variable si in the class declaration below should be defined separately:

    // LNK2019d.cpp
    #include <stdio.h>
    struct X {
       static int si;
    };
    
    // int X::si = 0;   // uncomment this line to resolve
    
    int main() {
       X *px = new X[2];
       printf_s("\n%d",px[0].si);   // LNK2019
    }
    

The following sample generates LNK2019 on a user-defined operator.

// LNK2019e.cpp
// compile with: /EHsc
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class 
Test {
   friend ostream& operator<<(ostream&, Test&);
   // Uncomment the following line to resolve.
   // template<typename T> friend ostream& operator << (ostream&, Test<T>&);
};

template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
   return os;
}

int main() {
   Test<int> t;
   cout << "Test: " << t << endl;   // unresolved external
}

The /VERBOSE linker option will help you see which files the linker is referencing. The /EXPORTS and /SYMBOLS options of the DUMPBIN utility can also help you see which symbols are defined in your dll and object/library files.

The Microsoft Knowledge Base has more information about LNK2019; see https://support.microsoft.com.

LNK2019 can also be generated as a result of conformance work that was done for Visual Studio .NET 2003: template friends and specialization. In Visual Studio .NET 2003, a declaration of a friend function with the same name as a function template does not refer to that function template unless template arguments are explicitly specified in the friend declaration.

If you do not specify template arguments, the friend declaration declares a non-template function.

See Summary of Compile-Time Breaking Changes for more information.

For code that is valid in both the Visual Studio .NET 2003 and Visual Studio .NET versions of Visual C++, explicitly specify the friend function's template argument list.

// LNK2019f.cpp
// LNK2019 expected
template<class T>
void f(T) {}

template<class T>
struct S {
   friend void f(T);
   // try the folowing line instead
   // friend void f<T>(T);
};

int main() {
   S<int> s;
   f(1);   // unresolved external
}

LNK2019 can also occur as a result of conformance work that was done in Visual C++ 2005, /Zc:wchar_t is now on by default. All modules may not have been compiled with the same /Zc:wchar_t settings, causing type references to not resolve to compatible types. To resolve, ensure that types in all modules are compatible, either by compiling with the appropriate /Zc:wchar_t settings (for example, using /Zc:wchar_t- when building modules with the Visual C++ 2005 toolset that will be linked with modules from previous versions) or, if possible, by updating your types so they are compatible.

Explicit references to comsupp.lib, either from the comment pragma or via the command line, should be changed to now use either comsuppw.lib or comsuppwd.lib, as /Zc:wchar_t is now on by default. comsupp.lib should still be used when compiling with /Zc:wchar_t-.

For more information, see Breaking Changes in the Visual C++ 2005 Compiler and /Zc:wchar_t (wchar_t Is Native Type).

The following sample creates an export that uses WCHAR, which resolves to wchar_t.

// LNK2019g.cpp
// compile with: /LD
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}

The following sample generates LNK2019:

// LNK2019h.cpp
// compile with: LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);

int main() {
   func(0);
}

To resolve this error, either change unsigned short to wchar_t or WCHAR, or compile LNK2019g.cpp with /Zc:wchar_t-.

You can also get LNK2019 if you are building a console application with /SUBSYSTEM:WINDOWS. The unresolved symbol will be _WinMain@16. In this case, just link with /SUBSYSTEM:CONSOLE.