Herding Cats and Organizing Includes

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