Reference to an unresolved external character (possible reasons)

When you try to build a program, you receive an error message of one of the following types:

  • reference to an unresolved external character ...
  • undefined character reference ...
  • unresolved external symbol ...
  • undefined reference to ...

What does this mean, and how do I fix this error?

 51
Author: Harry, 2016-06-19

2 answers

Definition

This error means that in the process of linking the program, the linker could not find the definition of some entity that is referenced (attempted use) in the program.

Such entities can include, for example, a function or a variable.


Reasons and solutions

There may be several possible reasons for the error, and it depends on what the project is being built. All the many situations are possible split into two large groups:


Third-party libraries are used

  • The required (static) library for the linker is not specified.

    For example, only a *.h file with declarations is connected to the project, but there is no implementation code, usually *.lib or *.a files (depending on the system used). You need to explicitly connect the library to the project.

  • For Visual C++, you can do this by adding the following line directly to the code:

    #pragma comment(lib, "libname.lib")
    
  • For gcc/clang , you need to specify the file via the key -l (el)

  • For Qt, in the .pro file, you need to use the variable LIBS:

    LIBS += -L[путь_к_библиотеке] -l[имя_библиотеки]
    
  • For the build system cmake there is target_link_libraries.

  • The library is specified, but the required entity, such as a class or function, is not actually exported from the library. Under Windows, it can occur due to absence __declspec(dllexport) before the entity. Usually this is solved by macros. This situation is most often typical for libraries that are in the process of development and are available for modification by the developer himself, rather than for some stable versions of libraries that are really external to the project. After allowing the export, the library, of course, must be rebuilt before directly using the problem library. entities.

  • The library is specified, but the bit depth of the library and the compiled code does not match.

    In general, the bit depth of the project (application or library) being built must match the bit depth of the third-party library being used. Usually library manufacturers provide the option to choose the 32 or 64 bit version to use. If the library is supplied in source code and is built separately from the current project, you must also select the correct one bit depth.

  • The library is specified, but it is built for a different (non-compatible) OS.

    For example, when building a project in Windows, an attempt is made to use a binary file that was built for Linux. In this case, you need to use files that are suitable for your OS.

  • The library is specified, but it is compiled by another compiler that is not compatible with the one used.

    Object files obtained by assembling C++ code by different compilers for the same OS may be binary incompatible with each other. You need to use compatible (most likely identical) compilers.

  • The library is specified, and is compiled by the same compiler as the main project, but different versions of the Run-Time libraries are used.

    For example, for Visual C++, it is possible that the library is built with the key /MDd, and the main project with /MTd. You need to set the keys so that the same versions of Run-Time are used libraries.


Third-party libraries are not used

  • There is simply no function definition.

    void f(int); // всего лишь объявление. Нет `тела` функции
    int main(){  
        f(42);   // undefined reference to `f(int)'
    }  
    

    You need to add a function definition f:

    void f(int) {
        // тело функции
    }
    

    There may also be a special case with an error of the form:

    undefined reference to `vtable for <имя_класса>`
    

    This error occurs if a declared virtual function of a class that is not pure (=0) does not contain an implementation.

    class C {
        virtual void f(int);
    };
    

    You need to add such an implementation. If it is it is done outside the class, you must not forget to specify the name of the problem class, otherwise it will just be a free function that does not fix the specified problem:

    void C::f(int) { // виртуальная функция-член вне определения класса
        // тело функции  
    } 
    
    void f(int) { // свободная функция, не устраняющая проблему
        // тело функции 
    } 
    

    A similar situation can occur when using namespaces when the function declaration is in the namespace:

    // В заголовочном файле
    namespace N {
        void f(int);
    };    
    

    And when implementing, you forgot to specify this namespace:

    // В файле реализации
    void f(int) { // функция в глобальном пространстве имён, не устраняющая проблему
        // тело функции  
    }
    
    namespace N {
    void f(int) { // функция в нужном пространстве имён
        // тело функции  
    }
    } // конец пространства имён
    
  • There is no definition of a static class variable.

    struct S {
        static int i;
    };
    
    int main() {
        S s;
        s.i = 42;  // undefined reference to `S::i'
    }
    

    Need to add defining (allocate memory) a variable:

    int S::i;
    
  • Incorrect implementation of the template code.

    For example, the template code implementation is placed in a *.cpp file, although it should be located entirely in the plug-in *.h file.

  • The code file was not compiled.

    For example, in the case of using a makefile, the rule for building a file was not specified, and in the case of using an IDE like Visual Studio *.cpp, the file was not added to the list project files.

  • A virtual function in the base class is not declared as = 0 (pure-virtual).

    struct B {
        void virtual f();
    };
    
    struct D : B {
        void f() {}
    };
    
    int main() {
        D d;
    }
    

    When using a class hierarchy, a function in the base class that has no implementation should be marked as "pure":

    struct B {
        void virtual f() = 0;
    };
    
  • The name has no external binding.

    For example, there is a function declaration f in the module А and even its implementation in the module B, but the implementation is marked as static:

    // A.cpp
    void f();
    int main() {
        f();   // undefined reference to `f()'
    }
    
    // B.cpp
    static void f() {}
    

    A similar one this situation may occur when using an unnamed namespace:

    // B.cpp
    namespace {
       void f() {}
    }
    

    Or even if the function has inline :

    // B.cpp
    inline void f() {}
    
 70
Author: αλεχολυτ, 2020-11-24 07:53:11

(In addition to the already existing answer)

  • When using Visual Studio or other compilers for the Windows platform, executing a project of the Windows Desktop Application type starts with the WinMain function, and executing a project of the Windows Console Application type starts with the main function.

    If your program is written in regular C or C++, i.e. it contains the standard classical function main, and you created your project by mistake with the type Windows Desktop Application, then when linking, you will get a message that the function WinMain was not found by the linker.

    Conversely, if you created a project of the type Windows Console Application, but instead of the function main defined the function WinMain in it, then when linking you will get a message that the function main was not found by the linker.

 15
Author: AnT, 2019-07-17 15:30:37