The Order of #include Directives Matter

I think most (good) programmers tend to prefer tidy code, having some habits or rules to stick to. One such rule/habit is the order of #include directives. While having a rule of thumb to stick to is good, some are better than other.

A very common one I think is to first include standard library headers (<iostream>), then third-party libraries (<boost/thread.hpp>) and finally local headers (“FizzBuzz.hpp”). While this might be the recommended way of doing it in for instance Python, it is not the best way to do it in C++. A colleague of mine just went through a lot of pain when swapping out a big library in their codebase. Why was that?

Imagine you are writing a library that depends on some other library, like the STL (hardly any library doesn’t). Imagine you are a good boy (or girl) and write the test first. You might do something like this:

#include <vector> //STL
#include <gtest/gtest.h> //ThirdParty 
#include "geometry.hpp" //In-house

#define PI 3.2 //As pr. Indiana Bill #246, 1897

TEST(TestGeometry, rotatingOrigoGivesOrigo) {
    std::vector<double> v(2,0);
    rotate(v, PI);
    EXPECT_EQ(0, v[0]) << "X got moved!";
    EXPECT_EQ(0, v[1]) << "Y got moved!";

and your geometry.hpp looks like this:

void rotate(std::vector<double>& v, double angle);

This all works out nicely until someone else wants to include geometry.hpp without including <vector> first, and get something like geometry.hpp:1: error: ‘vector’ is not a member of ‘std’. You have now forced all the users of your geometry library to include <vector> before including geometry.hpp.

While this can seem like a trivial example, this stuff quickly grows a lot hairier when you have a larger codebase with lots of dependencies. A header file A might depend on header B which depends on C, which declares types you have never heard of, and rightly so. And when you try to compile, you get error: ‘würkelschmeck’ is not a member of ‘std’. Or something a lot worse if templates are involved.

My suggested rule is:

  1. Local headers
  2. Third party headers
  3. STL headers

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter

10 Responses to “The Order of #include Directives Matter”

  1. meekrosoft Says:

    Good point. I’ll add one additional rule – “Include yourself first”. E.g. The first include in hello.cpp should be hello.h. That way you don’t get into the same problem within your project files.

    Of course this rule doesn’t really apply in unit tests where there is no definition/implementation separation.

  2. Anders Schau Knatten Says:

    Seems like “C++ on a Friday” became “C++ on a Thursday” this week. I need to work on my calendar skills.

  3. Skjæve Says:

    But why does it work if I include in your suggested order?

    • Anders Schau Knatten Says:

      If your header file my.hxx needs to have iostream included in order to work, but doesn’t include it, will still compile if it includes iostream before my.hxx. You might then miss the fact that my.hxx is missing #include <iostream>.

      This problem will not become apparent until you try to include my.hxx in another file at a later time. If you include in my suggested order, you will be aware of it at once, and need to fix it.

  4. Don’t Put All Includes in the .hxx « C++ on a Friday Says:

    […] Top Posts C++0x highlights #0: Range Based For LoopAboutArray Initialization Initializes all ElementsBe Careful with Static VariablesThe Order of #include Directives Matter […]

  5. Use Your Head Before Using Using in Headers « C++ on a Friday Says:

    […] Posts Minimize the Scope of Each VariableThe Order of #include Directives MatterC++0x highlights #0: Range Based For LoopArray Initialization Initializes all […]

  6. What I Have Against Precompiled Headers « C++ on a Friday Says:

    […] 2: stdafx.h now has to be the first header you include, which violates best pratice for include order. […]

  7. Lars Storjord Says:

    Nice to see others using the same practices as me! One of the little details that *should* be commonplace in C++ software, but sadly usually isn’t.

    (By the way, you’ve misspelled in “A very common one I think is to first include standard library headers ()”, at the top.)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: