Linker Tools Error LNK2019

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 documents:

The following sample generates LNK2019.

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

LNK2019 can also occur when a static data member is declared but not defined. 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 in the build, the linker will generate LNK2019. You can add these definitions by including as part of the compilation the source code file that contains the definitions. Alternatively, you can pass to the linker .obj files or .lib files that contain the definitions.

For C++ projects that were created in earlier releases and were upgraded to the current version, if __UNICODE was defined and the entry point was WinMain, you have to change the name of the entry point function to either _tWinMain or wWinMain.

Common problems that cause LNK2019 include these:

  • The declaration of the symbol is not spelled the same as the definition of the symbol.

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

  • Build dependency is only defined as project dependency in the solution. In earlier versions of Visual Studio, this level of dependency was sufficient. However, starting with Visual Studio 2010, Visual Studio requires a project-to-project reference. If your project does not have a project-to-project reference, you may receive this linker error.

  • 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. If this is the 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 in the following example 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 can help you ascertain which files the linker is referencing. The /EXPORTS and /SYMBOLS options of the DUMPBIN utility can also help you discover which symbols are defined in your .dll and object/library files.

For more information about LNK2019, see the Microsoft Support Web site.

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 that has 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.

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

// 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 be caused by conformance work that was done in Visual C++ 2005; that is, /Zc:wchar_t is now on by default. Modules may not all have been compiled by using the same /Zc:wchar_t settings; therefore, type references may not resolve to compatible types. Ensure that types in all modules are compatible, either by compiling by using the appropriate /Zc:wchar_t settings (for example, use /Zc:wchar_t- when you build modules with the Visual C++ tools that will be linked with modules from earlier versions) or, if possible, by updating the types so that they are compatible.

Change explicit references to comsupp.lib, either from the comment pragma or on the command line, to either comsuppw.lib or comsuppwd.lib; do this because /Zc:wchar_t is now on by default. Continue to use comsupp.lib when you compile by using /Zc:wchar_t-.

For more information, see /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, change unsigned short to wchar_t or WCHAR, or compile LNK2019g.cpp by using /Zc:wchar_t-.

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