This is one of those "should" rather than "shall" kinds of coding standards. The reason is that you would pretty much have to write a C++ parser to enforce it.
A very common rule for header files is that they must stand by themselves. A header file must not require that some other header files be #included before including the header in question. This is a testable requirement. Given some random header foo.hh
, the following should compile and run:
#include "foo.hh"
int main () {
return 0;
}
This rule has consequences with regard to use of other classes in some header. Sometimes those consequences can be avoided by forward declaring those other classes. This isn't possible with a lot of the standard library classes. There's no way to forward declare a template instantiation such as std::string
or std::vector<SomeType>
. You have to #include
those STL headers in the header even if the only use of the type is as an argument to a function.
Another problem is with stuff that you incidentally drag in. Example: consider the following:
file foo.cc:
#include "foo.hh"
#include "bar.hh"
void Foo::Foo () : bar() { /* body elided */ }
void Foo::do_something (int item) {
...
bar.add_item (item);
...
}
Here bar
is a class Foo
data member that is of type Bar
. You've done the right thing here and have #included bar.hh even though that would have to have been included in the header that defines class Foo
. However, you haven't included the stuff used by Bar::Bar()
and Bar::add_item(int)
. There are many cases where these calls can result in additional external references.
If you analyze foo.o
with a tool such as nm
, it will appear that the functions in foo.cc
are calling all kinds of stuff for which you haven't done the appropriate #include
. So should you add #include
directives for those incidental external references foo.cc
? The answer is absolutely not. The problem is that it is very hard to distinguish those functions that are called incidentally from the ones that are called directly.