October 19, 2020

Include Order Banner

Did you experienced a case where your header depends on another one? Why in that other C++ file, it compiles correctly without the same dependencies? If you encountered this default, maybe your header is not buildable as standalone. This default is easier to detect (and to fix!) with a single condition: Respect a certain include order.

Example of problematic include order: Incomplete header file.

Let’s review this example:

C++ - IDCard.hpp - Header missing

// IDCard.hpp

#pragma once

class ID_Card
{
public:
    ID_Card(std::string id) : id(id) {};
    ~ID_Card() {};
    const std::string get_id() const {return id;};
private:
    std::string id;
};

C++ - IDCard.cpp - Header missing

// IDCard.cpp

#include <string>
#include <iostream>
#include "IDCard.hpp"

int main()
{
    ID_Card my_id_card("Toto");
    std::cout << "This is the IDCard of " << my_id_card.get_id() << std::endl;
    return 0;
}

As you see, “string” is missing in my header file. However, due to the order of includes, the code compiles smoothly!

Here is the potential issue! IIf I simply move the <string> include after my "IDCard.hpp" one, I get an error:

C++ - IDCard.cpp - Changing order

#include "IDCard.hpp"
#include <iostream>
#include <string>

To avoid this case, you can apply a policy of coding style! Of course, this error is easy to detect in a short code. But what about a large project? When you should include 6 headers, this kind of error can be terrible.

A simple rule for include order: "The related header in first".

Even if include order differs following the coding style, one rule is in common. It is “The related header file is always the first one”. This simple rule guarantees that all your headers are buildable as standalone. Pretty great if you plan to code a dummy version of your class!

The advantage with this simple rule is you can detect early this inclusion error. Then, you can fix quickly this default to resolve some strange issues later!

Some examples of coding style.

You can obtain on the internet some great examples of coding rules like google and llvm.

Personally, I am using the following order:

  1. Related header.
  2. Local headers.
  3. Sub-Project headers.
  4. Third-Party headers.
  5. Systems  headers.

With this one, I can easily detect where come my different headers.

This is one of the potential issues due to include system. Later, maybe the module system is another alternative to resolve this!

About the author 

Axel Fortun

​Developer specialized in Linux environment and embedded systems.
​Knowledge in multiple languages as C/C++, Java, Python​ and AngularJs.
​Working as Software developer since 2014 with a beginning in the car industry​ and then in ​medical systems.