gpt4 book ai didi

C++ #include 语义

转载 作者:行者123 更新时间:2023-12-01 19:50:34 27 4
gpt4 key购买 nike

这是同一预处理指令的多个问题。
1 - <> 还是 ""?
除了在 MSDN 中找到的信息:
#include Directive (C-C++)
1.a:这两种符号有什么区别?
1.b:所有编译器都以相同的方式实现它们吗?
1.c:什么时候使用<>,什么时候使用“”(即,您将使用一个或另一个作为标题包含的标准是什么)?
2 - #include {TheProject/TheHeader.hpp} 或 {TheHeader.hpp} ?
我已经看到至少有两种写法包含一个人的项目标题。
考虑到您至少有 4 种类型的 header ,即:

  • 您项目的私有(private)标题?
  • 项目的标题,但它们导出符号(因此,“公共(public)”)
  • 您的模块与
  • 链接的另一个项目的标题
  • 编译器或标准库的头文件

  • 对于每种标题:
    2.a:你会使用 <> 还是 ""?
    2.b:你会包含在 {TheProject/TheHeader.hpp} 中,还是只包含在 {TheHeader.hpp} 中?
    3 - 奖金
    3.a:您是否在树状组织(即目录中的目录,而不是“一个目录中的每个文件”)中处理带有源和/或标题的项目,其优缺点是什么?

    最佳答案

    在阅读了所有答案以及编译器文档后,我决定遵循以下标准。
    对于所有文件,无论是项目 header 还是外部 header ,始终使用以下模式:

    #include <namespace/header.hpp>
    命名空间至少是一个目录深,以避免冲突。
    当然,这意味着项目头所在的项目目录也应该作为“默认包含头”添加到 makefile 中。
    之所以做出这样的选择,是因为我找到了以下信息:
    1. include ""模式依赖于编译器
    我会在下面给出答案
    1.a 标准
    来源:
  • C++14 工作草案 n3797:https://isocpp.org/files/papers/N3797.pdf
  • C++11、C++98、C99、C89(引用的部分在所有这些标准中都没有变化)

  • 在 16.2 源文件包含部分,我们可以看到:

    A preprocessing directive of the form

      #include <h-char-sequence> new-line

    searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.


    这意味着 #include <...> 将以实现定义的方式搜索文件。
    然后,下一段:

    A preprocessing directive of the form

      #include "q-char-sequence" new-line

    causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

      #include <h-char-sequence> new-line

    with the identical contained sequence (including > characters, if any) from the original directive.


    这意味着 #include "..."将以实现定义的方式搜索文件,然后,如果未找到该文件,则会进行另一次搜索,就好像它是一个 #include <...>
    结论是我们必须阅读编译器文档。
    请注意,出于某种原因,标准中没有任何地方区分“系统”或“库”标题或其他标题。唯一的区别似乎是 #include <...> 似乎针对标题,而 #include "..."似乎针对源(至少,在英文措辞中)。
    1.b Visual C++:
    来源:
  • http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx

  • #include "MyFile.hpp"
    预处理器按以下顺序搜索包含文件:
  • 在与包含 #include 语句的文件相同的目录中。
  • 在任何以前打开的包含文件的目录中,它们的顺序与它们打开的顺序相反。搜索从最后打开的包含文件的目录开始,并通过最先打开的包含文件的目录继续。
  • 沿着每个/I 编译器选项指定的路径。
  • (*) 沿着由 INCLUDE 环境变量或开发环境默认包含指定的路径。

  • #include
    预处理器按以下顺序搜索包含文件:
  • 沿着每个/I 编译器选项指定的路径。
  • (*) 沿着由 INCLUDE 环境变量或开发环境默认包含指定的路径。

  • 关于最后一步的注意事项
    该文档不清楚 <...> 的“沿着 INCLUDE 环境变量指定的路径”部分和 "..."包括。以下引用使其符合标准:

    For include files that are specified as #include "path-spec", directory searching begins with the directory of the parent file and then proceeds through the directories of any grandparent files. That is, searching begins relative to the directory that contains the source file that contains the #include directive that's being processed. If there is no grandparent file and the file has not been found, the search continues as if the file name were enclosed in angle brackets.


    因此,最后一步(用星号标记)是阅读整个文档的解释。
    1.c g++
    来源:
  • https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
  • https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html
  • https://gcc.gnu.org/onlinedocs/cpp/Include-Operation.html
  • https://gcc.gnu.org/onlinedocs/cpp/Invocation.html
  • https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
  • https://gcc.gnu.org/onlinedocs/cpp/Once-Only-Headers.html
  • https://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html
  • https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

  • 以下引述总结了该过程:

    GCC [...] will look for headers requested with #include <file> in [system directories] [...] All the directories named by -I are searched, in left-to-right order, before the default directories

    GCC looks for headers requested with #include "file" first in the directory containing the current file, then in the directories as specified by -iquote options, then in the same places it would have looked for a header requested with angle brackets.


    #include "MyFile.hpp"
    此变体用于您自己程序的头文件。预处理器按以下顺序搜索包含文件:
  • 在与包含 #include 语句的文件相同的目录中。
  • 沿着每个 -iquote 编译器选项指定的路径。
  • 至于#include <MyFile.hpp>

  • #include
    此变体用于系统头文件。预处理器按以下顺序搜索包含文件:
  • 沿着每个 -I 编译器选项指定的路径。
  • 在系统目录内。

  • 1.d Oracle/Sun Studio CC
    来源:
  • http://docs.oracle.com/cd/E19205-01/819-5265/bjadq/index.html

  • 注意文字有些自相矛盾(看例子理解)。关键短语是:“不同之处在于当前目录只搜索名称用引号括起来的头文件。”
    #include "MyFile.hpp"
    此变体用于您自己程序的头文件。预处理器按以下顺序搜索包含文件:
  • 当前目录(即包含“包含”文件的目录)
  • 用 -I 选项命名的目录,如果有的话
  • 系统目录(例如/usr/include 目录)

  • #include
    此变体用于系统头文件。预处理器按以下顺序搜索包含文件:
  • 用 -I 选项命名的目录,如果有的话
  • 系统目录(例如/usr/include 目录)

  • 1.e XL C/C++ 编译器引用 - IBM/AIX
    来源:
  • http://www.bluefern.canterbury.ac.nz/ucsc%20userdocs/forucscwebsite/c/aix/compiler.pdf
  • http://www-01.ibm.com/support/docview.wss?uid=swg27024204&aid=1

  • 这两个文档的标题都是“XL C/C++ 编译器引用”。第一个文档较旧(8.0),但更容易理解。第二个是较新的(12.1),但更难解密。
    #include "MyFile.hpp"
    此变体用于您自己程序的头文件。预处理器按以下顺序搜索包含文件:
  • 当前目录(即包含“包含”文件的目录)
  • 用 -I 选项命名的目录,如果有的话
  • 系统目录(例如/usr/vac[cpp]/include 或/usr/include 目录)

  • #include
    此变体用于系统头文件。预处理器按以下顺序搜索包含文件:
  • 用 -I 选项命名的目录,如果有的话
  • 系统目录(例如/usr/vac[cpp]/include 或/usr/include 目录)

  • 1.e 结论
    模式 ""可能会导致编译器之间的细微编译错误,而且由于我目前在 Windows Visual C++、Linux g++、Oracle/Solaris CC 和 AIX XL 上工作,这是 Not Acceptable 。
    无论如何,“”描述的特征的优势无论如何都远非有趣,所以......
    2. 使用 {namespace}/header.hpp 模式
    我在工作中看到(即这不是理论,这是现实生活中痛苦的职业经历)两个同名的header,一个在本地项目目录中,另一个在全局include中。
    由于我们使用了 ""模式,并且该文件同时包含在本地头文件和全局头文件中,因此当出现奇怪的错误时,无法理解真正发生了什么。
    使用包含中的目录可以节省我们的时间,因为用户必须编写:
    #include <MyLocalProject/Header.hpp>
    或者
    #include <GlobalInclude/Header.hpp>
    你会注意到,虽然
    #include "Header.hpp"
    会编译成功,因此,仍然隐藏问题,而
    #include <Header.hpp>
    在正常情况下不会编译。
    因此,坚持 <> 符号会使开发人员强制使用正确的目录作为包含的前缀,这是更喜欢 <> 而不是 ""的另一个原因。
    3. 结论
    同时使用 <> 符号和命名空间符号可以从预编译器中消除猜测文件的可能性,而不是只搜索默认的包含目录。
    当然,标准库还是照常包含的,即:
    #include <cstdlib>
    #include <vector>

    关于C++ #include 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/179213/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com