C++ 是否对C+有任何标准要求+#包括查找?

C++ 是否对C+有任何标准要求+#包括查找?,c++,c-preprocessor,include-path,C++,C Preprocessor,Include Path,最近,gnu cpp和msvc cl以不同的方式处理#include文件。常见的行为是查看include___________________________________________________ 但是现在我想知道:我学习正确了吗,或者说预处理器实际上也有一个标准吗?根据该标准,\include和\include“…”将搜索一组实现定义的位置。甚至不要求在或“之间提供的名称是文件名,只要求它允许头的唯一标识 话虽如此,如果一个实现希望编译现有的源代码,它最好遵循与其他实现相同的约定:指

最近,gnu cpp和msvc cl以不同的方式处理
#include
文件。常见的行为是查看include___________________________________________________


但是现在我想知道:我学习正确了吗,或者说预处理器实际上也有一个标准吗?

根据该标准,
\include
\include“…”
将搜索一组实现定义的位置。甚至不要求在
之间提供的名称是文件名,只要求它允许头的唯一标识

话虽如此,如果一个实现希望编译现有的源代码,它最好遵循与其他实现相同的约定:
指的是系统包含文件,
“…”
指的是您自己的包含文件(应该首先搜索包含源文件的目录)。这些都不是标准中的要求,但是如果没有它们,您就无法编译任何现有的代码


该标准在某些地方有点精神分裂——在一个地方,它将为您提供处理文件和目录的工具(C++17中的文件系统扩展),而在另一些地方,它拒绝承认文件和目录之类的东西甚至存在。这大概是因为作者不想把太多的文本弄乱,因为它现在工作得很好,可能只是偶然地打破了一些东西,但看起来确实有点可笑。

< P> > H. Gujit的回答,C语言和C++语言标准都没有提供任何保证。但是POSIX标准确实提供了一些关于
cpp
(CPreP处理器)如何工作的额外保证:

因此,应首先在带有
#include
行的文件目录中搜索名称包含在双引号(
)中的标题,然后在
-I
选项中命名的目录中搜索,最后在通常的位置搜索。对于名称包含在尖括号(“
”)中的标题,应仅在
-I
选项中命名的目录中搜索标题,然后在通常位置搜索标题

根据标准(16.2[cpp.include]/2),
\include

在实现定义的位置序列中搜索标题 由
分隔符。如何指定位置或识别标题 实现定义。[重点补充]

相比之下(16.2[cpp.include]/3),
#include“…”

导致该指令被的全部内容替换 源文件
分隔符之间的指定序列标识。在 实现定义的方式。如果不支持此搜索,或者如果搜索失败,则将重新处理该指令,就像它读取
#包括
具有与原始指令相同的包含序列(包括
字符,如果有的话)。[强调添加]

因此,位置和技术都是完全定义的实现,除了
#include“…”
如果在初始搜索中没有找到源文件,则返回到
#include

措辞上的差异很重要:
#include
不需要源文件;它完全取决于它如何处理标准头文件的实现。用户编写的头文件应该
#include>一起拉入。。。“
,因为这是处理源文件所必需的


在大多数情况下,编译器以您期望的方式实现这些功能。MSVC的关键区别在于,对于
#include“…”
,它首先在正在编译的顶级源文件的目录中搜索,而其他编译器首先在当前正在编译的源文件的目录中搜索。当头文件具有
#include“…”指令时,这一点很重要:大多数编译器在头文件所在的目录中搜索,但MSVC的搜索就像
#include“…”指令在顶级源文件中一样。这两种方法都是有效的,而且两种方法都有各自的理由,尽管我个人认为搜索头所在的目录更直观,也更容易使用。

标准甚至没有提到源文件,也没有要求宿主文件系统甚至有目录,所以很难标准化。这些编译器之间有什么不同?@MatteoItalia,用词不当。[lex.separate]定义了“源文件”,而[cpp]讨论了如何包含它们。它可能在使用它们的意义上与您略有不同,但它确实在谈论它们。
\include“…”
需要一个源文件
#include
指的是不必是源文件的头文件。@PeteBecker我想你的意思是相反的。不。请看我的答案,它列出了标准中的文本。好吧,那样的话,你就大错特错了。根据您引用的文本,
“…”
可能指的是源文件或头文件-不要求它是源文件<代码>
指的是一个标题,只是一个标题。哦,我明白你的意思。但这并不是“相反”,只是我夸大了对
#include“…”
的要求。顺便说一句,这个答案没有提到的要求。