If your compilation gets stuck on an error „improper include order”, this means you are using clang-tidy with enabled checks for correct order of included header files. Of course, the simple solution to that is to try to move problematic lines up or down and try again until they are success. But if you don’t understand what is the rule behind this order, you will probably make the same mistake in the future. The good news is that in this article I will explain it so you can avoid it in the future.
Before we start with the main topic, let’s explain one thing, because many people probably wonder if this check is necessary? No, it’s not, but it helps ensure consistency and readability in your code, so I would recommend you to try using this order:
- Main header file for the implementation file:
If your implementation file is „my_lib.c” , it would be „my_lib.h” - System headers:
All libraries that provide an interface to the underlying operating system. They are not a part of the C language itself, but they are provided by the operating system or platform to get access to system-level functionalities. Very often the are part of the POSIX standard on Unix operating systems. Library „<unistd.h>” is an good example here, it provides functions that can interact with OS kernel, such as „fork()”, „exec()”, „read()”, „write()”. - Standard library headers:
Collection of libraries that are part of the C programming language specification. These libraries are designed to provide a set of commonly used functions, available across all implementations of C language, for example „string.h” for manipulating strings, „stdio.h” for handling input/output data or „stdint.h” for mathematic operations - Other libraries’ headers:
Headers from third-party libraries that are not a C standard library, like the popular „cjson.h”. It doesn’t matter if it’s compiled as part of the project or used like a pre-compiled shared library. - Project headers:
Finally, at the end, all include headers from your own project. The preferred way is to group them by the module they belong to and order lexicographically within each group.
Below there is a general example for this order:
// Main header file for this implementation file.
#include "my_lib.h"
// System headers.
#include <unistd.h>
// C standard library headers.
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdint.h>
// Other libraries' headers.
#include <cjson/cjson.h>
// Project headers.
#include "foo/foo.h"
#include "bar/bar.h"
#include "some_module/my_module.h"
This is the end. Thanks for reading this article. I hope it will be usefull. Happy coding 🙂