-
Notifications
You must be signed in to change notification settings - Fork 206
Include order
John Haddon edited this page Dec 20, 2019
·
1 revision
We follow a strict set of conventions for the ordering of #includes
, partly for readability, but more importantly to allow us to wrangle various issues in the libraries we depend on. These conventions were first adopted in https://github.com/GafferHQ/gaffer/pull/2431, and were necessary for us to properly manage symbol visibility.
// File GafferScene/Instancer.cpp (simplified and annotated)
// ==============================
// If in a cpp file, include the header for that file first
#include "GafferScene/Instancer.h"
// All other includes are grouped by module and ordered from highest-level
// to lowest-level. Within a module, includes are sorted alphabetically.
#include "GafferScene/SceneAlgo.h"
#include "Gaffer/Context.h"
#include "Gaffer/StringPlug.h"
#include "IECore/DataAlgo.h"
#include "IECore/MessageHandler.h"
#include "IECore/NullObject.h"
#include "boost/lexical_cast.hpp"
#include "tbb/blocked_range.h"
#include "tbb/parallel_reduce.h"
#include <functional>
#include <unordered_map>
- In a Foo.cpp file, the equivalent Foo.h header is the first include. Rationale : This proves that Foo.h is a standalone header, not relying on other stuff being included first. Adopting this convention highlighted several existing errors.
- Headers are then included with the highest level projects first, down to system headers last. Rationale :
- Some high level headers need to work around problems with lower-level headers, and to do so they need to come first. For instance, the problems described in https://github.com/ImageEngine/cortex/commit/8e2d356f570a28a87f7628d14fbc4bc7f4f9ed48#diff-472bb092433c363608dd9b24fdb806ffR48.
- Foo.h is the highest level header, and is first anyway.
- Includes from within the same project (i.e. all IECore headers) are ordered alphabetically within their section. Rationale :
- Makes it harder to accidentally include the same header twice.
- If it must be included, boost/python.hpp comes first. It has always needed to be first so it can work around weird problems created by the python headers - it's a good example of the "high level header needs to fix problems in low level header" thing.
- Finally, we make the odd inexplicable change required by Clang. Rationale : I am a mortal, and Clang is a god.