【发布时间】:2011-05-06 07:48:45
【问题描述】:
如果我有自己的库项目,我应该使用哪种样式来#include 我的应用程序中的标头?是否有严格的规则,两者对编译器/预处理器实际上有不同的含义还是仅与标准有关?
【问题讨论】:
标签: c++ header-files
如果我有自己的库项目,我应该使用哪种样式来#include 我的应用程序中的标头?是否有严格的规则,两者对编译器/预处理器实际上有不同的含义还是仅与标准有关?
【问题讨论】:
标签: c++ header-files
根据 ISO 标准,规则很少。两种形式都取决于它们在哪里寻找头文件。他们甚至不必成为文件。
C++11 的 2.9 部分没有区分这两个变体,除了可以在<> 变体中包含" 和在"" 变体中包含>,但很少有人会傻到在文件名中使用这些字符:-)
16.2 部分进一步说明:
# include < h-char-sequence> new-line形式的预处理指令在实现定义的位置序列中搜索由<和>分隔符之间的指定序列唯一标识的标头,并导致该指令由整个标头的内容。如何指定位置或标识的标头是实现定义的。
# include " q-char-sequence" new-line形式的预处理指令导致将该指令替换为由"分隔符之间的指定序列标识的源文件的全部内容。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者搜索失败,则重新处理该指令,就好像它使用与原始指令相同的包含序列(包括 > 字符,如果有)读取# include < h-char-sequence> new-line。
我倾向于将<> 用于系统标头,将"" 用于我自己的标头,但这只是个人喜好。我会注意到前面提到的 C++11 文档指出:
注意:虽然实现可以提供一种机制,使任意源文件可用于
<>搜索,但通常程序员应使用<>形式作为实现提供的标头,而""形式用于源不受实施的控制。
这不是强制性的,但它仍然是一个好主意。
【讨论】:
. 放在你的 -I 路径中。然而,这个问题被标记为 C++,这就是我调用该标准的原因。但是看到更新,ISO 建议如何使用这两种类型,但没有强制要求。
通常,使用引号表示头文件位于项目目录的相对位置。另一方面,如果您使用尖括号,编译器会期望您的头文件位置是标准位置。例如/usr/include、/usr/local/include 或您的编译器的任何其他默认位置。
在 GCC 中,如果您使用 -I 标志,也会在指定位置搜索带尖括号的包含。
例子:
$ gcc -Wall -I/path/to/my/library/include myfile.c
因此,如果您在/path/to/my/library/include 中有myfile.h,则可以在myfile.c 源中使用#include <myfile.h>。
【讨论】:
在几个不同的操作系统上使用了数十种编译器之后,我的建议是仅将 <x.h> 用于系统和特定于操作的标头包含,而将 "y.h" 用于其他所有内容,包括您的库和项目标头。
然后您使用编译器的-I(或其他)选项设置适当的包含搜索路径。如果您使用 make 或 ant 之类的东西来进行构建,这会更容易。
对于第三方软件标头,您可以使用任何一种形式。如果软件包已安装并且可供所有用户访问(例如,在 /usr/local/bin 或 /usr/site/bin 之类的地方),那么 <x.h> 形式可能更正确。如果它安装在您的本地构建树中,那么 "y.h" 形式更正确,因为它在您的构建过程中进行控制。
这种组合是最便携的。
【讨论】:
它影响预处理器搜索包含文件的位置。来自 MSDN:
"引用形式:此形式指示预处理器在包含#include 语句的文件的同一目录中查找包含文件,然后在包含(#include)该文件的任何文件的目录中查找包含文件。预处理器然后沿着 /I 编译器选项指定的路径搜索,然后沿着 INCLUDE 环境变量指定的路径搜索。
尖括号形式:此形式指示预处理器首先沿着 /I 编译器选项指定的路径搜索包含文件,然后在从命令行编译时,沿着 INCLUDE 环境变量指定的路径搜索包含文件。”
作为一个粗略的指南,我只在尝试指定相对于包含带有#include 的文件的目录的路径时才使用引号。否则,我只使用尖括号。以我目前的项目为例:
#include <algorithm> // standard library headers
#include <numeric>
#include <stack>
#include <boost/function.hpp> // third-party library headers
#include <boost/lexical_cast.hpp>
#include <common/io/util/LineIO.h> // specified relative to my own base include dir
#include "PartitionForest.h" // a header in the current directory
【讨论】: