Herding Cats and
Organizing Includes
Sergey Prigogin
Google
CDT committer, refactoring component lead
Copyright (c) 2013 Google. Made available under the Eclipse Public License v1.0.
Why Organize Includes?
o Required for new refactorings (Inline, Change
Method Signature)
o Useful by itself. Bugzilla enhancement request
45203 was created in October 2003 and has 47
comments
Why is so difficult?
What needs to be organized?
Ø Includes
Ø Forward declarations
!
#include <string>!
std::string concatenate(const std::string& pieces...);!
!
using std::string;!
void main(int argc, const char* argv[]) {!
string s = concatenate(argv[1], argv[2]);!
...!
}!
Include vs forward-declare
A foo(A a) {
// definition of
return a;!
}!
!
A* bar(A* a) {
// definition of
return a;!
}!
!
void baz(A* a) {!
a->f();
// definition of
}!
!
class C {!
D x;
// definition of
static E y;
// definition of
};!
!
!
A is required!
A is not required!
A is required!
D is required!
E is not required!
Who is responsible for inclusion?
MyString.h
class MyString {!
public:!
MyString(const char* s);!
};!
!
Compare.h
class MyString;
// is forward declaration enough?!
int compare(const MyString& s1, const MyString& s2);!
!
main.cpp
#include "Compare.h"!
int main(int argc, const char* argv[]) {!
return compare(argv[1], argv[2]);!
}!
!
Indirect inclusion
GC.h
class GC { ... };!
!
Graphics.h
#include ”GC.h"!
inline void drawLine(int x1, int y1, int x2, int y2) {!
GC.getCurrent().drawLine(x1, y1, x2, y2);!
}!
main.cpp
#include "Graphics.h"!
void main() {!
drawLine(0, 0, 1, 1);!
GC gc;!
...!
}!
!
More about indirect inclusion
Ø Include What You Use principle
o https://code.google.com/p/include-what-you-use/w/list
Ø Representative header files
o <vector>, not <bits/stl_vector.h>!
o NULL is defined in 13 headers
Include pragmas
facade.h
#include "detail/constants.h" // IWYU pragma: export!
#include "detail/types.h" // IWYU pragma: export!
#include <vector>!
!
main.cpp
#include "facade.h”!
#include <vector>!
!
std::vector<Thing> things(MAX_THINGS);!
Include pragmas
facade.h
// IWYU pragma: begin_exports!
#include "detail/constants.h"!
#include "detail/types.h"!
// IWYU pragma: end_exports!
#include <vector>!
!
main.cpp
#include "facade.h”!
#include <vector>!
!
std::vector<Thing> things(MAX_THINGS);!
Private and public headers
component/*.h can be included from
anywhere
component/internal/*.h can be included
only from component/*.* and component/
internal/*.*!
More include pragmas
!
// IWYU pragma: private, include "public.h"!
!
// IWYU pragma: private!
// IWYU pragma: friend ”internal/.*”!
!
// IWYU pragma: no_include "private.h”!
!
// IWYU pragma: no_forward_declare MySymbol!
!
#include <vector> // IWYU pragma: keep!
!
Flavors of include statements
Ø Angle brackets or quotes
#include <vector>!
#include "my_vector"!
Ø Short or long path
#include "point.h"!
#include "graphics/primitives/point.h"!
Grouping and ordering of includes
Ø With the same name but different extension
Ø In the same folder
Ø In subfolders
Ø “System” includes
Ø User-defined groups
Grouping example
/MyProject/src/time/DateTime.cpp
#include
!
#include
#include
#include
#include
!
#include
#include
!
#include
#include
#include
!
... !
"time/DateTime.h"!
<sys/time.h>!
<time.h>!
<cstdio>!
<string>!
"time/Duration.h"!
"time/timezone/TimeZone.h"!
"base/Types.h"!
"strings/Format.h"!
"util/Logging.h"!
Preferences, preferences, preferences…
Ø Inclusion vs forward declaration
Ø Header file substitution
Ø Style of include statements
Ø Grouping and ordering
Ø What to do with unused includes
Give Feedback on the Sessions
1
2
Sign In: www.eclipsecon.org
Select Session Evaluate
Herding Cats
and Organizing
Includes
Evaluate
3
Vote
© Copyright 2026 Paperzz