C/C++ include header file order
Solution 1:
I don't think there's a recommended order, as long as it compiles! What's annoying is when some headers require other headers to be included first... That's a problem with the headers themselves, not with the order of includes.
My personal preference is to go from local to global, each subsection in alphabetical order, i.e.:
- h file corresponding to this cpp file (if applicable)
- headers from the same component,
- headers from other components,
- system headers.
My rationale for 1. is that it should prove that each header (for which there is a cpp) can be #include
d without prerequisites (terminus technicus: header is "self-contained"). And the rest just seems to flow logically from there.
Solution 2:
The big thing to keep in mind is that your headers should not be dependent upon other headers being included first. One way to insure this is to include your headers before any other headers.
"Thinking in C++" in particular mentions this, referencing Lakos' "Large Scale C++ Software Design":
Latent usage errors can be avoided by ensuring that the .h file of a component parses by itself – without externally-provided declarations or definitions... Including the .h file as the very first line of the .c file ensures that no critical piece of information intrinsic to the physical interface of the component is missing from the .h file (or, if there is, that you will find out about it as soon as you try to compile the .c file).
That is to say, include in the following order:
- The prototype/interface header for this implementation (ie, the .h/.hh file that corresponds to this .cpp/.cc file).
- Other headers from the same project, as needed.
- Headers from other non-standard, non-system libraries (for example, Qt, Eigen, etc).
- Headers from other "almost-standard" libraries (for example, Boost)
- Standard C++ headers (for example, iostream, functional, etc.)
- Standard C headers (for example, cstdint, dirent.h, etc.)
If any of the headers have an issue with being included in this order, either fix them (if yours) or don't use them. Boycott libraries that don't write clean headers.
Google's C++ style guide argues almost the reverse, with really no justification at all; I personally tend to favor the Lakos approach.
Solution 3:
I follow two simple rules that avoid the vast majority of problems:
- All headers (and indeed any source files) should include what they need. They should not rely on their users including things.
- As an adjunct, all headers should have include guards so that they don't get included multiple times by over-ambitious application of rule 1 above.
I also follow the guidelines of:
- Include system headers first (stdio.h, etc) with a dividing line.
- Group them logically.
In other words:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
Although, being guidelines, that's a subjective thing. The rules on the other hand, I enforce rigidly, even to the point of providing 'wrapper' header files with include guards and grouped includes if some obnoxious third-party developer doesn't subscribe to my vision :-)
Solution 4:
To add my own brick to the wall.
- Each header needs to be self-sufficient, which can only be tested if it's included first at least once
- One should not mistakenly modify the meaning of a third-party header by introducing symbols (macro, types, etc.)
So I usually go like this:
// myproject/src/example.cpp
#include "myproject/example.h"
#include <algorithm>
#include <set>
#include <vector>
#include <3rdparty/foo.h>
#include <3rdparty/bar.h>
#include "myproject/another.h"
#include "myproject/specific/bla.h"
#include "detail/impl.h"
Each group separated by a blank line from the next one:
- Header corresponding to this cpp file first (sanity check)
- System headers
- Third-party headers, organized by dependency order
- Project headers
- Project private headers
Also note that, apart from system headers, each file is in a folder with the name of its namespace, just because it's easier to track them down this way.