In a typical C ++ project, you compile each of the implementation files (or .cpp ) separately - you never pass the header file (or .h ) to the compiler directly. After pre-processing and inclusion, each of these files becomes a translation unit. So, in the example that you specified, there are two translation units that look like this:
main.cpp translation unit:
// Contents of <iostream> header here int myCoolFunction(); int myAwesomeFunction() // Note implementing function in header { return 3; } int main() { std::cout << myAwesomeFunction() << std::endl; }
something.cpp translation unit:
int myCoolFunction(); int myAwesomeFunction() // Note implementing function in header { return 3; } int myCoolFunction() { return 4; }
Note that both of these translation units contain duplicate content because they both included something.h . As you can see, only one of the listed translation units contains the definition of myCoolFunction . It's good! However, both of them contain a definition of myAwesomeFunction . This is bad!
After the translation units are compiled separately, they are then linked to the final program. There are certain rules for multiple declarations between translation units. One of these rules (Β§3.2 / 4):
Each program must contain exactly one definition of each non-built-in function or variable that is odr-used in this program; no diagnostics required.
You have several myAwesomeFunction definitions in your program, and therefore you are breaking the rules. This is why your code is referencing incorrectly.
You can think of it from the point of view of the linker. After these two translation units are compiled, you have two object files. The task of the linker is to merge the object files together to form the final executable. Thus, he sees the call to myAwesomeFunction in main and tries to find the corresponding function definition in one of the object files. However, there are two definitions. Linker does not know which one to use, so that he simply gives up.
Now let's see what the translation units look like if you define myAwesomeFunction in something.cpp :
Fixed translation unit main.cpp :
// Contents of <iostream> header here int myCoolFunction(); int myAwesomeFunction(); int main() { std::cout << myAwesomeFunction() << std::endl; }
Fixed translation unit something.cpp :
int myCoolFunction(); int myAwesomeFunction(); int myCoolFunction() { return 4; } int myAwesomeFunction() { return 3; }
Now thatβs fine. Currently, there is only one definition of myAwesomeFunction for the entire program. When the linker sees a call to myAwesomeFunction in main , he knows exactly in which function definition he must refer.
source share