Short answer: YES.
The clang-format
tool has a -sort-includes
option. Changing the order of #include
directives can definitely change the behavior of existing code, and may break existing code.
Since the corresponding SortIncludes
option is set to true
by several of the built-in styles, it might not be obvious that clang-format
is going to reorder your includes.
MyStruct.h:
struct MyStruct {
uint8_t value;
};
original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
Now let’s say we run clang-format -style=llvm original.c > restyled.c
.
restyled.c:
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Due to the reordering of the header files, I get the following error when compiling restyled.c
:
In file included from restyled.c:1:
./MyStruct.h:2:5: error: unknown type name 'uint8_t'
uint8_t value;
^
1 error generated.
However, this issue should be easy to work around. It’s unlikely that you have order-dependent includes like this, but if you do, you can fix the problem by putting a blank line between groups of headers that require a specific order, since apparently clang-format
only sorts groups of #include
directives with no non-#include
lines in between.
fixed-original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
fixed-restyled.c:
#include <stddef.h>
#include <stdint.h>
#include "MyStruct.h"
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Note that stdint.h
and stddef.h
were still reordered since their includes are still “grouped”, but that the new blank line prevented MyStruct.h
from being moved before the standard library includes.
However…
If reordering your #include
directives breaks your code, you should probably do one of the following anyway:
-
Explicitly include the dependencies for each header in the header file. In my example, I’d need to include
stdint.h
inMyStruct.h
. -
Add a comment line between the include groups that explicitly states the ordering dependency. Remember that any non-
#include
line should break up a group, so comment lines work as well. The comment line in the following code also preventsclang-format
from includingMyStruct.h
before the standard library headers.
alternate-original.c:
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}