Question:
For C++ - Where should I define my functions, in the header file or the .cpp file?
?
2014-11-06 14:38:51 UTC
Can someone tell me where I should define my functions in C++ ? I was told that I should only declare my functions in the header, and then write their definitions in the .cpp file. What is the reason for this? And is there ever a situation where it is appropriate to write the definitions in the header?
Seven answers:
mark_poc
2014-11-06 22:31:33 UTC
I will add in my 2.8 cents worth.



Whenever you are using functions, the compiler doesn't need the function code itself, that is, it doesn't need the function definition, just the call to the function. It couldn't care less if the actual code for the function didn't even exist - that's not it's problem. It's only job is to make the call to the function - whether it exists or not. So, if the compiler comes across a function named foo(x,y) it translates it something like this:



push x;

push y;

jmp to location foo ???;



The compiler pushes a copy of x and y onto the stack to be retrieved by foo's function code. It also pushes the current location in memory onto the stack first so it can return to this same point after the function is done (returns). Then it makes a jump to the actual code of the function which is somewhere in memory. But the compiler has no idea where in memory the function code is located, so it just uses ??? for the address, which the Linker will fill in later. This is called an external reference (to foo).



In the early days, the compiler didn't need to have a function prototype. It just went ahead and pushed the parameters onto the stack and generated the jump instruction to location foo ???. But what if the programmer made a mistake and passed an int to the function when it was supposed to be a double? A hard to find bug would result. To prevent this, it became required to provide a prototype so the compiler would have something to compare the call of the function by the programmer to, and if discrepancies were found an error would be issued. So that is why you need a prototype (declaration). The compiler doesn't need it to code the call, but just to check the programmers work in calling the function, and will issue an error if a prototype isn't provided.



Let's say that you had two .cpp files, one called source1.cpp which holds your main source code and one called functions.cpp which held all of the actual code for your functions (definitions). And let's say that you had a third file called myHeader.h which had all of the prototypes for your functions (declarations). Now when you start to compile your program, the first thing that happens is that the compiler's pre-processor reads in the myHeader.h file into source1.cpp, because of this statement: #include"myHeader.h" (or #include in the case of library files). Then the compiler will go ahead a compile the two .cpp files into two .obj (object) files. These object files are pretty much ready to run, except for any external references, like jump to foo ???, that need to be resolved. Then the Linker program goes to work and joins the files and reads the file to locate any external references and resolves them. For example, the line "jump to foo ??? will be replaced with "jump to 154628" which is where foo's code is located. If the Linker can't find the foo function it will issue an error message. Or if it find's two or more foo functions it won't know which one to use and will issue an error for that as well. So obviously, there needs to be just one copy of the code for a function or else the ambiguity will result in a Link error. So if everything goes well then all of the external references will have been filled in within the object file and an executable file (.exe) will be ready to run. That is just the basic idea involved, it is actually just a little different because the code has to be relocatable in memory so relative addresses are used but the basic principle is the same.



You can repeat a declaration as many times as you want, but only one definition will work. You could put your definitions in the header file so long as you only used the header file once. If you use it twice, like in two .cpp files associated with your program, then the Linker won't know which copy to use. If you don't want the code for the functions messing up your main .cpp file, then make a separate .cpp file for the function definitions, one .h file for the declarations and then the main .cpp file. Or, as an illustration, you could have each function definition in a separate .cpp file. So then you may end up with ten .cpp files and one .h file for all of the declarations. After you ran the compiler, you would have ten object files which the Linker would combine into one object file. Then the Linker would resolve all the external references and produce an executable file.



But if you just have a few functions, you can define them after the main function and include the declarations at the top, or you can do the definitions at the top and then they will also serve as the declarations. You could also place the definitions after main and make a separate .h file for your declarations and #include" name" at the top.
justme
2014-11-06 15:25:22 UTC
If you have just one .c (.cpp) file you can declare the functions in that file, along with the actual function. In fact, if the function is placed in the file before it is actually used (called), you don't even need to declare it.



Header files are useful when you have multiple .c (.cpp) files using the same functions. You declare the functions in the header file, and include the header file in the .c (.cpp) files. The function itself should be in a .c (.cpp) file though since these are the files that actually get compiled. You can put macros in a header file, but all the compiler does is replace the macro name with its actual code when compiling.
Tom
2014-11-06 22:24:20 UTC
Putting implementation in your header basically forces the compiler to pull the code into the "includers" compilation unit. This is sometimes done as a performance optimization, but usually not needed.



The other reason you may put implementation in header is if you shipping a library with headers and you want part of your code to run in the "includers" DLL/SO space. This is sometimes needed to deal with ABI funnies which you can have.



However rule of thumb is to define your functions/method prototypes in the header and your implementation in the C/CPP file.



Going to the other extreme, it is sometimes good practice to use PIMPL design pattern in C++ for classes. The allows you to not expose any implementation details in your header and only expose a clean API.
Jeff
2014-11-06 14:58:10 UTC
It is convention that functions are declared in the header and defined in the cpp file.

It's sometimes fine to define functions in the header file if they are tiny like min or max functions or itty bitty things. It also makes it more convenient when you want to share the public functions with someone else but you don't want to share the definitions or how you did it behind the scenes. This is how closed source software works.
Jeroonk
2014-11-06 15:21:01 UTC
On large C/C++ projects, compilation happens in stages. Instead of compiling all the files together, every single .cpp file is compiled as its own little unit. Once the final executable is being "linked", all these units are combined to form a program. There are a couple of reasons for doing it this way, one being speed (not having to recompile everything after a change), another the ability to separate or bundle and distribute sections of the code as libraries, or even "link" at the very last second using run-time libraries (DLLs).



So each .cpp file is independent, with the compiler having no knowledge of the contents of another .cpp file. But how then does the compiler know how to call functions from one file to the other? By reading the function declaration in the associated header file. Note that compiler only needs to know *how* to call the function, the actual function won't be available until the program is linked with the compiled file that contains the definition.



- Header files are for declarations, which "advertise" the functions you can call if you link with the corresponding .cpp file.

- The .cpp file is for the actual implementation of the functions, which is executed when a call is made.





Putting the function definition in a header can be dangerous. Example:



- Header "a.h" defines the function "int a()"

- Source "x.cpp" includes header "a.h"

- Source "y.cpp" includes header "a.h"



Now both x and y will compile just fine, independently from each other. But when the program is linked together, there are now two definitions of the same function (one for each file that included the header)! Your build will fail with a very confusing error.



The correct way:



- Header "a.h" declares the prototype "int a();"

- Source "a.cpp" defines the function "int a()"

- Source "x.cpp" includes header "a.h"

- Source "y.cpp" includes header "a.h"



When the program is compiled, x and y will know how to call "int a()", because they had the declaration from the header, and when the program is linked, there will be just one version of "int a()", namely the one from "a.cpp". Build successful.
?
2014-11-06 14:49:36 UTC
The header is supposed to contain an outline of the actual .cpp file. It contains the signatures, and the function bodies go into the main file.

I'm no C++ expert, but I can't imagine a situation where one would need to declare functions in the header so I assume it's not possible.
?
2014-11-06 15:25:16 UTC
Function prototypes, that you want to expose outside your current compilation unit (i.e. the .cpp file), should be in the .h file.

Implementation of the functions go in the .cpp file.



Why: Say your code, in file "myfile.cpp", has a function abc() which will be used by the code in file "yourfile.cpp". You put the function prototype in "myfile.h" and the implementation in "myfile.cpp".

Then to use function abc(), in "yourfile.cpp", you put a #include "myfile.h" in it. This tells the compiler that to put in the object code for "yourfile.cpp" (i.e. yourfile.o) so it can call function abc().



Then after you have compiled "myfile.cpp" and "yourfile.cpp", so you have "myfile.o" and "yourfile.o" you use the linker (for small programs this is done automatically by the compiler), to link the two object files together and resolve any unresolved references. In this case "yourfile.o" has a reference to abc(), which is implemented in "myfile.o", so the linker links the references to abc() in "yourfile.o" to the implementation in "myfile.o"



Probably more than you wanted to know, right?



Now consider this: If you put the implementation of abc() into "myfile.h" then when you compile "myfile.h" (which would have a #include "myfile.h" you will have an implementation of function abc(). No problem.

But then when you compiler "yourfile.cpp", which also includes "myfile.h", you will have a second implementation of abc(), in "yourfile.o" instead of having an unresolved reference to abc().

So when you go to link "myfile.o" and "yourfile.o" you have two functions named abc(), which would be a problem.



Clear as mud, right?



For simplicity just put function prototypes in .h files, and put the function implementations in .cpp files. Then you don't have to think about and try to fix these weird linker errors.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...