Well they were probably referring to a couple of things ("include creep" is not a term I've ever heard before). If you, as an extreme rule, only include headers from headers (aside from one matching header per source file):
- Compilation time increases as many headers must be compiled for all source files.
- Unnecessary dependencies increase, e.g. with a dependency based build system, modifying one header may cause unnecessary recompilation of many other files, increasing compile time.
- Increased possibility of namespace pollution.
- Circular dependencies become an issue (two headers that need to include each other).
- Other more advanced dependency-related topics (for example, this defeats the purpose of opaque pointers, which causes many design issues in certain types of applications).
As a general rule of thumb, include the bare minimum number of things from a header required to compile only the code in that header (that is, enough to allow the header to compile if it is included by itself, but no more than that). This will combat all of the above issues.
For example, if you have a source file for a class that uses std::list
in the code, but the class itself has no members or function parameters that use std::list
, there's no reason to #include <list>
from the class's header, as nothing in the class's header uses std::list
. Do it from the source file, where you actually need it, instead of in the header, where everything that uses the class also has to compile <list>
unnecessarily.
Another common technique is forward declaring pointer types. This is the only real way to combat circular dependency issues, and has some of the compilation time benefits listed above as well. For example, if two classes refer to each other but only via pointers:
// A.h
class B; // forward declaration instead of #include "B.h"
class A {
B *b;
}
// B.h
class A; // forward declaration instead of #include "A.h"
class B {
A *a;
}
Then include the headers for each in the source files, where the definitions are actually needed.