22

From what I have read and understood, the #include directive in a source file, like for ex: main.cpp, just copies the content of the included file to the .cpp. So, when I include a header file, for ex: yum.h, all the statements in yum.h are copied into main.cpp.

The header file will just have declarations and the actual definition will be in a corresponding .cpp file, like yum.cpp.

So, while compiling main.cpp, how will the compiler know to look for the definition of any function mentioned in yum.h in yum.cpp? How will the compiler know to complie the yum.cpp file too, as there is no reference to it in either main.cpp file or yum.h.

Also, why should yum.h be included in yum.cpp?

This may sound like a stupid question. I am a beginner to OOP and C++, and am just trying to understand what is happening.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
GRANZER
  • 355
  • 3
  • 13
  • You need to compile both cpp files. You include the h file so the compiler knows these functions exist. When you link the program the compiler uses the correct definition from the compiled unit – mdatsev Jan 11 '18 at 16:03
  • 1
    Do you have experience with any programming language that has compiler and linker tools? – PM 77-1 Jan 11 '18 at 16:04
  • 2
    https://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work – wavemode Jan 11 '18 at 16:04
  • 1
    The compiler doesn't need to see the definitions in the corresponding `cpp` file, that's what the header is for, to provide the parts the compiler needs. it is the **linker** that stitches the program parts together, this question may have answers to your question: https://stackoverflow.com/questions/9529571/c-compiler-and-linker-functionality – Galik Jan 11 '18 at 16:04
  • @Ron thank you for the list. I am using c++ primer 6th edition and OOP in c++ by Rober Lafore. – GRANZER Jan 11 '18 at 16:09
  • @mdatsev thank you for the answer. How does the compiler know to look for the definition in the .cpp or the corresponding .o file? The header file has no reference to the corresponding .cpp file where the definition of the function resides. – GRANZER Jan 11 '18 at 16:09
  • 1
    This is why (imo) it's best to start programming **without** an IDE that does this behind your back. Work from the command line with a good text editor at the beginning. That way, when you do use and `IDE` (and you should) you will understand how to use the `IDE` because you know what it's doing for you behind the scenes. – Galik Jan 11 '18 at 16:16
  • @Galik Thank you. Ya learning without an IDE would be the best way but most books and tutorials does use IDEs to hide the complexities in the beginning I guess. – GRANZER Jan 12 '18 at 06:34

3 Answers3

27

Short answer: there is no relationship between the header and its implementation. One can exist without the other, or the two could be placed in files with unrelated names.

while compiling the main.cpp how will the compiler know to look for the definition of any function mentioned in yum.h in yum.cpp?

The compiler has no idea. Each time it sees a reference to something declared in yum.h, or in any other header file, for that matter, it stays on a lookout for the corresponding definition.

If the definition is not there by the time the compiler has reached for the end of translation unit, it writes unsatisfied references into its main.o output, noting the places from which they are coming from. This is called a symbol table.

Then the compiler compiles yum.cpp, finds definitions from yum.h in it, and writes their positions into yum.o's symbol table.

Once all cpp files have been processed, linker grabs all .o files, and builds a combined symbol table from them. If unsatisfied references remain, it issues an error. Otherwise, it links references from main.o with the corresponding symbols from yum.o, completing the process.

Consider an example: let's say yum.h declares a global variable int yum = 0 defined in yum.cpp, and main.cpp prints that variable. The compiler produces main.o with a symbol table saying "I need int yum's definition at address 1234", and yum.o file's symbol table saying "I have int yum at address 9876". Linker matches the "I need" with "I have" by placing 9876 at the address 1234.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
4

The compiler does not need to look for anything in other code files.
The result of compilation is an object file, which has placeholders for whatever is defined in other code files. For making those placeholders, the compiler only needs the information provided by a suitable header (declarations, prototypes etc.).
The step of filling in the placeholders is the job of the linker, which is theoretically separate tool from the compiler. ("theoretically" as in "could be a single tool behaving like two separate tools.)

The reason for including the header with the declarations into the code file which does the implementing (of all or part of what gets declared) is a widely spread best practice, because it allows the compiler to complain if implementation and declaration do not match.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Thank you. I now understand that the object file is not stand alone and the IDEs usually hide the linking part is 'build' in VS. – GRANZER Jan 12 '18 at 06:42
2

So while compiling the main.cpp how will the compiler know to look for the definition of any function mentioned in yum.h in yum.cpp?

Compiler does not. When it produces object file (this is result of compiling) it says there - call function such and such. Then there is linking process, where all object files and libraries are linked together to produce executable. As linker sees all object files and libs it know where to find that function (or produces error, if it cannot find it).

ie how will compiler know to complie the yum.cpp file too as there is no reference to it in either the main.cpp file or yum.h file.

Compiler does not know that either. It is programmer job to tell compiler to compile all necessary source file into object ones and pass them all to linker. It can be done inside IDE which could be hidden from you or you may have to do that manually using utility make for example.

Also why should yum.h included in yum.cpp

When you compile C++ program you usually have classes and their methods. To be able to use class in other source files it's definition must be visible there, so it goes to a header. Methods, when implemented inside .cpp file also must be declared inside class first, so that .cpp has to include it's header. And even for standalone functions it is just cleaner to let compiler match signature in header to signature in implementation.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • Thank you very much. I was seeing it the wrong way. Now I am clear that both the .cpp files have to be compiled and have object file. Am I write to say that the linker will search the current directory for the file with the definition? ie if a header file multiple function declarations and the definition for each one of them is in separate .cpp file the linker has to search for them(ie the corresponding .O file) or I will have to provide the path to the corresponding object file? – GRANZER Jan 12 '18 at 06:40