What do I have to consider when putting all code in the header?

164 Views Asked by At

I found several places where it is discussed whether it is better to put definitions in headers or not (e.g. here). However, I could not find something like a "guide to header-only code". The answer to the linked question mentions some downsides:

  • increased compile time
  • not possible to have circular dependencies
  • no (simple) global objects

But is that all?

What are the consequences of putting (all) code in the header?

Am I save if I use header guards, or are there other pitfalls?

The reason I am asking this is the following: I am in a situation where I think it would easiest to put all the code in my header files. It is a (rather small) collection of classes and functions that is supposed to be included by others in their code. It is supposed to be used in different environments and in different frameworks. At the moment, I do not see why I should build my code (into a lib), when the one using it can simply include the header she/he needs and compile it. However, independent of this project I always have a "bad feeling" when putting code in headers, even if none of the 3 points I mentioned above matters. Would be really nice if someone could shed some light on this for me so I can make the decision where to put the code on a more reasonable basis.

2

There are 2 best solutions below

8
On

There are several examples of brilliant libraries implemented mostly in header files, e.g. the std library or boost. In particular, if you want to distribute a template library, you have you have no real alternative.

Worst consequences of such an approach, imho, are:

  • exploding of compilation time: every edit you make to your code, you'll have to rebuild all files that include that header; this is a really serious issue, unless you keep using the ".h"/".cpp" approach while developing and then rearrange your code into the header just at the end
  • binary code bloat: all your functions will have to be declared "inline", so you may have a performance improvement but you may (1) also have a replication of binary code every time you use a function

(1) see Klaus comment and inline description at cppreference.com (quoted below):

The intent of the inline keyword is to serve as an indicator to the optimizer that inline substitution of the function is preferred over function call, that is, instead of executing the call CPU instruction to transfer control to the function body, a copy of the function body is executed without generating the call. This avoids extra overhead created by the function call (copying the arguments and retrieving the result) but it may result in a larger executable as the code for the function has to be repeated multiple times. Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those choices do not change the rules regarding multiple definitions and shared statics listed above.

0
On

Starting from my personal experience, I usually put only one-line functions (getters and setters) in the header file because all other function bodies will make the header file difficult to read and understand at a glance. Moreover if your project needs to include the header file multiple times (and you wrote function code in it), you would have an icreasing compile times since all code has to be processed every time it is included by the compiler.