Minimal Header Inclusion
Rule
Transitive inclusion: If header A is included by header B, and source file C already includes B, then C can reference everything from A without explicitly including A.
- •Include only what you directly need.
- •Do not add an include for a header that is already pulled in by another header you include.
When to Apply
- •Adding new
#includedirectives in a.cppor.hfile. - •Reviewing or refactoring include lists.
- •After lint or a code review flags redundant or unnecessary includes.
Guidelines
- •In a .cpp file: Include the header that declares the types/functions you use directly. If that header already includes others (e.g. your project’s base headers), do not duplicate those includes.
- •In a header: Include only headers required for that header’s own declarations. Prefer forward declarations when a pointer/reference is enough to avoid pulling in heavy headers.
- •Remove redundant includes: If you remove the last use of a symbol from header X, remove
#include "X"if X is only needed transitively via another included header.
Example
- •
foo.hincludesbar.h. - •
bar.hincludesbaz.h. - •In
impl.cppyou only use types frombar.handbaz.h.
Then impl.cpp should include foo.h (or bar.h if that’s the direct dependency), and should not add #include "baz.h" just because it uses symbols from baz.h—they are already available via foo.h → bar.h → baz.h.
Exceptions
- •If a symbol is only guaranteed by a particular standard or platform header (e.g. you rely on
<cstddef>forstd::size_t), including that header in the file that uses it can be acceptable for clarity or portability, even if it might come in transitively. Prefer the minimal set unless the team explicitly documents otherwise. - •When a header’s transitive includes are unstable or not part of the public contract, the team may choose to include the needed header explicitly for stability; follow project rules in that case.