Stop using #include in your headers

In Rob Pike's famous "Notes on Programming in C" he states a simple rule on include files: include files should never include include files. Mr. Pike argues that this solves the problem of multiple inclusions as well as speeding up compilation time since we potentially skip the lexical analysis of thousands of lines of code. There are tricks with #pragma once in recent compilers to help with this, but I digress.

I think Mr. Pikes argument fails to emphasize what I believe is the main benefit of not including headers in headers.


When I use a library and the header files defines something generic like, say, a likely/unlikely pair, it has a tendency to clash with my own "standard library". By all means, provide the likely/unlikely functions in your library distribution if you really think your user will need it, but please, allow the user to opt in by sticking it into a likely.h header that you only include in your source files. Please do NOT include it in your library.h file! Doing it like this also means that you can use it internally without constantly adding a mylibrary_ prefix on all your helper functions because you are afraid of name clashing. The benefit of this is huge to your users. They can mix and match and include just what they need.

Now, if you take this to the next level (that you really should aspire too), you do this with your library itself. You MAY provide a "bundle" header that includes everything, but make sure all it does is include everything else.

At first your users may complain that they need to "dig through the source to find the required headers" (argh, reading code you rely on, what a hazzle!). Stick a comment in your header that indicates what it relies on. In time, your users will thank you.

Stop using include guards

If you follow the above advice, there is no reason to use them. They are a hack anyway. If you rely on compilation units to include the header files they will not be included multiple times in any case.

In conclusion,

Compilation units needs header files. A header file does NOT. Header files should only define types and (possibly inline) functions.