Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are function bodies in C/C++ placed in separate source code files instead of headers?

For instance, when I define a class file in C++ I've always put the function bodies in the class header files(.h) along with the class definition. The source code file(.cpp) is the one with the main() function. Now is this commonly done among pro c++ programmers or do they follow the convention of separate header/source code files.

As for Native C, I do notice then done in GCC(and of course for the headers in Visual Studio for Windows).

So is this just a convention? Or is there a reason for this?

like image 376
SavedbyZer0 Avatar asked Dec 19 '17 01:12

SavedbyZer0


People also ask

Why do we separate header and source files?

The need for header files results from the limitations that the compiler has for knowing about the type information for functions and or variables in other modules. The compiled program or library does not include the type information required by the compiler to bind to any objects defined in other compilation units.

Why include header files instead of C files?

Because the C-library contains pre-compiled versions of the library functions that are then linked with your source file by the linker. You need to differentiate between header files, source files, object files, and library files.

Should you put functions in header files?

No. If you import the same header from two files, you get redefinition of function. However, it's usual if the function is inline. Every file needs it's definition to generate code, so people usually put the definition in header.

What is the difference between header files and source files?

Usually, header files contain declarations, source files contain code. So, if in source file A.c you need a function implemented in source file B.c , you just include B.h to have its declaration.


2 Answers

Function bodies are placed into .cpp files to achieve the following:

  1. To make the compiler parse and compile them only once, as opposed to forcing it to compile them again, again and again everywhere the header file is included. Additionally, in case of header implementation linker will later have to detect and eliminate identical external-linkage functions arriving in different object files.

    Header pre-compilation facilities implemented by many modern compilers might significantly reduce the wasted effort required for repetitive recompilation of the same header file, but they don't entirely eliminate the issue.

  2. To hide the implementations of these functions from the future users of the module or library. Implementation hiding techniques help to enforce certain programming discipline, which reduces parasitic inter-dependencies between modules and thus leads to cleaner code and faster compilation times.

    I'd even say that even if users have access to full source code of the library (i.e. nothing is really "hidden" from them), clean separation between what is supposed to be visible through header files and what is not supposed to be visible is beneficial to library's self-documenting properties (although such separation is achievable in header-only libraries as well).

  3. To make some functions "invisible" to the outside world (i.e. internal linkage, not immediately relevant to your example with class methods).

  4. Non-inline functions residing in a specific translation unit can be subjected to certain context-dependent optimizations. For example, two different functions with identical tail portions can end up "sharing" the machine code implementing these identical tails.

    Functions declared as inline in header files are compiled multiple times in different translation units (i.e. in different contexts) and have to be eliminated by the linker later, which makes it more difficult (if at all possible) to take advantage of such optimization opportunities.

  5. Other reasons I might have missed.

like image 84
AnT Avatar answered Sep 23 '22 13:09

AnT


It is a convention but it also depends on the specific needs. For example if you are writing a library that you want the functionality to be fast (inline) and you are designing the library for others to use to be a simple header only library, then you can write all of your code within the header file(s) itself.

On the other hand; if you are writing a library that will be linked either statically or dynamically and you are trying to encapsulate internal object data from the user. Your functions - class member functions etc. would be written in a manner that they do what they are supposed to do so as to where the user of your library code shouldn't have to worry about the actual implementation details for that part is hidden. All they would need to know about your functions and classes are their interfaces. It would be in this manner that you would have both header files and implementation files.

If you place your function definitions in the header files along with their declarations, they will be inline and should run faster however your executable will be larger and they will have to be compiled every time. The implementation details are also exposed to the user.

If you place your function definitions in the header's related code file they will not be inline, your code will be smaller, it may run a little slower, but you should only have to compile them once. The implementation details are hidden and abstracted away from the user.

like image 29
Francis Cugler Avatar answered Sep 22 '22 13:09

Francis Cugler