应该以什么顺序指定包含文件,即包含一个头文件在另一个头文件之前的原因是什么?
例如,系统文件、STL和Boost是在本地包含文件之前还是之后?
应该以什么顺序指定包含文件,即包含一个头文件在另一个头文件之前的原因是什么?
例如,系统文件、STL和Boost是在本地包含文件之前还是之后?
当前回答
我不认为有一个推荐的顺序,只要它编译!令人恼火的是,有些头文件需要先包含其他头文件……这是头文件本身的问题,而不是包含顺序的问题。
我个人倾向于从局部到全局,每个小节按字母顺序排列,即:
H文件对应此CPP文件(如适用) 来自同一个组件的头文件, 来自其他组件的头文件, 系统头文件。
我的理由是1。它应该证明每个头文件(其中有cpp)可以在没有先决条件的情况下被#包含(terminus technicus:头文件是“自包含的”)。剩下的似乎就从这里顺理成章地展开了。
其他回答
这不是主观的。确保你的头文件不依赖于以特定顺序被#包含。可以肯定的是,不管你以什么顺序包含STL或Boost头文件。
我遵循两个简单的规则来避免绝大多数问题:
所有的头文件(实际上包括任何源文件)都应该包含它们所需要的内容。他们不应该依赖于他们的用户,包括东西。 作为补充,所有的头文件都应该包含保护,这样它们就不会因为过于雄心勃勃地应用上述规则1而被多次包含。
我还遵循以下准则:
首先使用分隔线包含系统头文件(stdio.h等)。 将它们进行逻辑分组。
换句话说:
#include <stdio.h>
#include <string.h>
#include "btree.h"
#include "collect_hash.h"
#include "collect_arraylist.h"
#include "globals.h"
虽然,作为指导方针,这是主观的事情。另一方面,我严格执行规则,甚至提供'包装'头文件包含保护和分组包含,如果一些讨厌的第三方开发人员不同意我的愿景:-)
在决定特定的包含顺序时,需要合并几个单独的考虑事项。让我试着理清头绪。
1. 检查自制力
许多回答认为,include顺序应该作为头文件是否自包含的检查。这就混淆了测试和编译的考虑
您可以单独检查您的头文件是否自包含。“静态分析”是独立于任何编译过程的。例如,运行
gcc headerfile.h -fsyntax-only
测试头文件是否自包含可以很容易地编写脚本/自动化。甚至你的makefile也可以这样做。
无意冒犯,但Lakos的书是1996年的,把这些不同的问题放在一起听起来像90年代风格的编程。也就是说,有些生态系统(现在的Windows还是90年代的Windows ?)缺乏脚本/自动化测试的工具。
2. 可读性
另一个考虑因素是可读性。当您查找源文件时,您只想轻松地查看包含了哪些内容。因为你的个人品味和喜好是最重要的,尽管通常情况下你要么按照最具体到最不具体的顺序排列,要么相反(我更喜欢后者)。
在每个组中,我通常只是按字母顺序排列。
3.包含顺序重要吗?
如果头文件是自包含的,那么从技术上讲,包含顺序对编译结果应该没有任何影响。
也就是说,除非您对代码有特定的设计选择(有问题吗?),比如没有自动包含的必要宏定义。在这种情况下,您应该重新考虑您的程序设计,尽管它当然可能非常适合您。
我不认为有一个推荐的顺序,只要它编译!令人恼火的是,有些头文件需要先包含其他头文件……这是头文件本身的问题,而不是包含顺序的问题。
我个人倾向于从局部到全局,每个小节按字母顺序排列,即:
H文件对应此CPP文件(如适用) 来自同一个组件的头文件, 来自其他组件的头文件, 系统头文件。
我的理由是1。它应该证明每个头文件(其中有cpp)可以在没有先决条件的情况下被#包含(terminus technicus:头文件是“自包含的”)。剩下的似乎就从这里顺理成章地展开了。
我很确定这在任何理智的世界里都不是一个推荐的实践,但我喜欢按文件名长度排列系统包含,在相同的长度内按词法排序。像这样:
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
我认为在其他人之前包含自己的头文件是一个好主意,以避免包含顺序依赖的耻辱。