【问题标题】:What are the rules on #include "xxx.h" Vs #include <xxx.h>? [duplicate]#include "xxx.h" 与 #include <xxx.h> 的规则是什么? [复制]
【发布时间】:2011-05-06 07:48:45
【问题描述】:

如果我有自己的库项目,我应该使用哪种样式来#include 我的应用程序中的标头?是否有严格的规则,两者对编译器/预处理器实际上有不同的含义还是仅与标准有关?

【问题讨论】:

    标签: c++ header-files


    【解决方案1】:

    根据 ISO 标准,规则很少。两种形式都取决于它们在哪里寻找头文件。他们甚至不必成为文件。

    C++11 的 2.9 部分没有区分这两个变体,除了可以在&lt;&gt; 变体中包含" 和在"" 变体中包含&gt;,但很少有人会傻到在文件名中使用这些字符:-)

    16.2 部分进一步说明:


    # include &lt; h-char-sequence&gt; new-line 形式的预处理指令在实现定义的位置序列中搜索由&lt;&gt; 分隔符之间的指定序列唯一标识的标头,并导致该指令由整个标头的内容。如何指定位置或标识的标头是实现定义的。

    # include " q-char-sequence" new-line 形式的预处理指令导致将该指令替换为由" 分隔符之间的指定序列标识的源文件的全部内容。以实现定义的方式搜索命名的源文件。如果不支持此搜索,或者搜索失败,则重新处理该指令,就好像它使用与原始指令相同的包含序列(包括 > 字符,如果有)读取 # include &lt; h-char-sequence&gt; new-line


    我倾向于将&lt;&gt; 用于系统标头,将"" 用于我自己的标头,但这只是个人喜好。我会注意到前面提到的 C++11 文档指出:

    注意:虽然实现可以提供一种机制,使任意源文件可用于&lt;&gt; 搜索,但通常程序员应使用&lt;&gt; 形式作为实现提供的标头,而"" 形式用于源不受实施的控制。

    这不是强制性的,但它仍然是一个好主意。

    【讨论】:

    • 我没有意识到这是完全由实现定义的。但是,当且仅当您使用引号时(至少)gcc 搜索当前目录这一事实意味着您当然不应该在自己的标题中使用尖括号,对吧?
    • 如果 gcc 是这样(我没有理由怀疑你),那么是的,除非你把 . 放在你的 -I 路径中。然而,这个问题被标记为 C++,这就是我调用该标准的原因。但是看到更新,ISO 建议如何使用这两种类型,但没有强制要求。
    • 仍然不太清楚我公司代码库中用于各种应用程序的库的界限在哪里。他们有点像第 3 方,因为它可能是一个单独的团队,但不完全是。我倾向于将“xxx.h”用于 this 项目中的包含,而 用于单独项目中的任何内容。
    【解决方案2】:

    通常,使用引号表示头文件位于项目目录的相对位置。另一方面,如果您使用尖括号,编译器会期望您的头文件位置是标准位置。例如/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 &lt;myfile.h&gt;

    【讨论】:

      【解决方案3】:

      在几个不同的操作系统上使用了数十种编译器之后,我的建议是仅将 &lt;x.h&gt; 用于系统和特定于操作的标头包含,而将 "y.h" 用于其他所有内容,包括您的库和项目标头。

      然后您使用编译器的-I(或其他)选项设置适当的包含搜索路径。如果您使用 makeant 之类的东西来进行构建,这会更容易。

      对于第三方软件标头,您可以使用任何一种形式。如果软件包已安装并且可供所有用户访问(例如,在 /usr/local/bin/usr/site/bin 之类的地方),那么 &lt;x.h&gt; 形式可能更正确。如果它安装在您的本地构建树中,那么 "y.h" 形式更正确,因为它在您的构建过程中进行控制。

      这种组合是最便携的。

      【讨论】:

        【解决方案4】:

        它影响预处理器搜索包含文件的位置。来自 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
        

        【讨论】:

          猜你喜欢
          • 2012-04-25
          • 1970-01-01
          • 2012-11-20
          • 1970-01-01
          • 2011-06-11
          • 2013-05-17
          • 2012-05-27
          • 1970-01-01
          • 2017-05-08
          相关资源
          最近更新 更多