How does Main.cpp see the definition of getSquarePerimeter that's inside Square.cpp if it was never #include into Main.cpp? |
Building a program involves two steps: compilation and linking. First all files are compiled and then the results of those compilations are linked together.
If the compiler sees a definition, it will compile it and output it to the object file, but it if sees a declaration and a usage (calling or getting the address of the function) of that declaration it will instead add an item to the external references in the object file saying "I need function foo".
When the linker goes to link everything together, it should be able to see all definitions. It will go through the external references list of every object file and for every external reference it will scan the file looking for that reference and insert the correct address. If it doesn't know the address then that means a function was declared but not defined, or that a library file was not linked it; then it will generate a linker error complaining about an undefined or unresolved reference.
The second question is how come this code wont work - it looks like it should to me. The solution to making the code work is to remove the definition from Square.h into Square.cpp and have getSquareSides simply be a forward declaration - but what does that change to make it work? |
When you #include a header in a source file, you're doing the equivalent as copy-pasting the text of the header into the source. If you do that in this case, every source file will have a definition for getSquareSides(). The compiler will accept this just file, because it can't see other source files being compiled, and will compile the function and output the generated code to the object file. But the linker will be able to see that you made defined the same function multiple times. A function must be defined exactly once. The linker is not able to resolve this situation, so it just generates a linker error about multiple defintions.
By the way, another solution would be to make the function
static inline. Then the linker will accept multiple definitions and will deal with it accordingly.
Lastly, even if you don't include #include Square.h in Square.cpp, the compiler will still assume that that Square.cpp is defining the already declared getSquareSides and getSquarePerimeter - how? How does the compiler assume that the definitions for them are in Square.cpp if Square.h was never #Include into Square.cpp? |
Defining a function also implicitly declares it. Declaration serves two purposes. First, to state the presence of functions accross separate translation units. Second, to state the presence of functions within the same translation unit when the order of declaration and usage do not match. As an example for this second situation, consider this:
1 2 3 4 5 6 7 8 9 10
|
//Uncomment to allow this to compile:
//void bar();
void foo(){
bar();
}
void bar(){
foo();
}
|
If you don't declare bar() before foo() is defined, the compiler won't know that the function exists anywhere.
If neither case is applicable, then there's no need to declare the function in addition to defining it.