我们有很多代码,我们想用clang格式进行格式化.这意味着很多代码行会改变.不必检查由于clang格式而改变的每一行代码都将是此过程的一个简单的过程.
我会说clang格式不会改变代码如何工作.另一方面,我不能100%肯定,如果这可以保证.
解决方法
clang-format工具具有-sort-includes选项.更改#include指令的顺序可以改变现有代码的行为,并且可能会破坏现有的代码.
由于相应的SortIncludes选项被多个内置样式设置为true,所以clang格式将会重新排序包含可能并不明显.
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; }
现在我们来运行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; }
由于头文件的重新排序,编译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.
但是,这个问题应该很容易解决.您不太可能按照这样的顺序进行包装,但是如果您这样做,您可以通过在需要特定订单的标题组之间放置一个空白行来解决问题,因为显然,clang-format只能将#include指令与没有非#包含行之间的行.
固定original.c:
#include <stdint.h> #include <stddef.h> #include "MyStruct.h" int main (int argc,char **argv) { struct MyStruct s = { 0 }; return s.value; }
固定restyled.c:
#include <stddef.h> #include <stdint.h> #include "MyStruct.h" int main(int argc,char **argv) { struct MyStruct s = {0}; return s.value; }
请注意,stdint.h和stddef.h仍然重新排序,因为它们的包含仍然是“分组的”,但是新的空白行阻止MyStruct.h在标准库包含之前被移动.
然而…
如果重新排序你的#include指令会打破你的代码,你应该可以执行以下操作之一:
>明确地包含头文件中每个头的依赖关系.在我的例子中,我需要在MyStruct.h中包含stdint.h.
>在明确声明排序依赖关系的包含组之间添加注释行.请记住,任何非#包含行应该分解一个组,因此注释行也工作.以下代码中的注释行也阻止了在标准库头之前包含MyStruct.h的clang格式.
交替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; }