Unresolved external symbol What have I done wrong?


I've been trying to solve a problem for a while, I've tried to solve it with different compilers and there's no way. The program is more complex but I have been able to summarize it in the following code:

#ifndef S_HPP
#define S_HPP

struct S
    int uno();
    int dos();

#include "S.hpp"

int S::uno() { return 1; }
#include "S.hpp"

#include <iostream>

int main()
    S s;

    std::cout << s.uno() + s.dos() << '\n';

    return 0;

The errors I have are the following:

GCC HEAD 8.0.0 201704
/tmp/ccRBiKEw.o: In function 'main':
prog.cc:(.text+0x1f): undefined reference to 'S::dos()'
collect2: error: ld returned 1 exit status
clang HEAD 5.0.0
/tmp/prog-8f7223.o: In function 'main':
prog.cc:(.text+0x20): undefined reference to 'S::dos()'
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)

Can someone tell me what's wrong?

asked by PaperBirdMaster 16.05.2017 в 22:48

1 answer



This is a common problem in C ++ , which usually goes unnoticed in much more complex codes but in your case it is very easy to locate:

You lack the definition of the function S::dos


Add this line in S.cpp :

int S::dos() { lo que toque... }


The linker has not been unable to find the Translation Unit where the function S::dos was defined, and when trying to generate the program it has failed because it was missing one of the necessary pieces.

To understand this, we must know the concept of Translation Unit .

Translation Unit (UdT).

A UdT is roughly the intermediate result of processing and compiling a code file. That is, the preprocessor has done its tasks (include headers #include , expand macros #define , discard compiled code conditional #ifdef , #else , #endif ) and the compiler has made a compilation with the resulting file, this compilation goes to a object file and the link between archives objects is what ends up generating the program final.

Since an UdT contains the result of compiling code, only object files will generate those code files that contain compilable code; In other words, a code file that only contains declarations (for example a header .h or .hpp 1 ) will not generate an object file nor will it consist of a UdT but a code file with definitions (for example a file .c or .cpp 1 ) will be a UdT and will generate an object file.

Each UdT will have the entities (objects, functions, enumerated) that have been compiled in its object file:

In this example the object S has two functions ( S::uno and S::dos ) that are compiled and end up in the object file S.obj which is the binary representation of the UdT of S.cpp . If in some other point of the program the use of an object of type S is required (because someone has included S.hpp and has used some of its functions) the linker will search the object file containing these functions and use it to create the final program. The definitions of an object do not have to be in a single code file, they can be scattered in other files and each of them will create your UdT :

It will be the linker that is responsible after putting all the pieces together to create the program, but if among all the object files available for the linker, any of the required definitions are not found, a link failure will be caused as the one that have you experienced:

1 The extension of the file is irrelevant, the important thing is the content of the file.

answered by 16.05.2017 / 22:52