Consider a foo.cpp
file with the following content
#include "foo.hpp"
int foo() {
return 7;
}
and its associated header
#pragma once
int foo();
The latter is obviously needed to make aware the following main
function of the existence of foo
:
#include <iostream>
#include "foo.hpp" // to make the name `foo` available
int main() {
std::cout << foo() << std::endl;
}
However, the #include "foo.hpp"
seems to be redundant. Is there any reason I should keep it?
I've seen this practice in the codebase where I work on, but I guess there's many examples available in open source. For instance, as an example picked at random, look at src/builtin_builtin.h
and src/builtin_bultin.cpp
from the fish-shell
code base: the former, beside the include guard, has
just
#include
,One could put 2 in a fwd header, include it in the cpp file together with 1, and then the cpp file wouldn't need anymore to include its own header.
Some reasons to include the header (fpp.hpp
) from its implementation file (fpp.cpp
):
If you include foo.hpp
first in foo.cpp
, then compilation of foo.cpp
acts as a test that foo.hpp
is self-contained, meaning it can be successfully compiled without including anything else first. The Google C++ coding guidelines specifically recommend including the associated header first.
It is good practice for foo.hpp
to declare everything that foo.cpp
exports, and for everything else in foo.cpp
to have internal linkage in order to not pollute the global namespace. The GCC option -Wmissing-declarations
will report deviations from that practice, but it only works if foo.cpp
includes foo.hpp
.
Sometimes (often, in fact), including foo.hpp
is needed so foo.cpp
will compile. Most commonly, foo.hpp
defines a type that foo.cpp
needs, but it can also happen that function declarations are needed due to use before definition. I recommend to just do so consistently rather than trying to deduce whether it's necessary in each case.
Occasionally, the compiler can diagnose mismatches between declarations and definitions. A nasty case I've seen is a header declaring a global int x
but the implementation file defining long x
. Waste a day debugging that mistake, and I predict you'll resolve to include the associated header every time thereafter!
Finally, there are no good reasons not to include the associated header. In particular, omitting that include will almost never make a measurable difference to compile time. There are ways of dramatically improving compile times by restructuring header dependencies (for example, use of forward headers), but this isn't one of them.
Acknowledgments: Point 1 was noted by BoP in a comment. MSalters' answer notes points 3 and 4.