更新:2025-02-14 17:12:44|关注1 人
将其他源文件包含到当前源文件中紧随指令之后的一行。
#include < h字符序列 > 换行 | (1) |
#include " q字符序列 " 换行 | (2) |
#include 记号序列 换行 | (3) |
__has_include ( " q字符序列 " ) __has_include ( < h字符序列 > ) | (4) |
__has_include ( 字符串字面量 ) __has_include ( < h记号序列 > ) | (5) |
1) 搜索由 h字符序列 唯一识别的标头,并将该指令替换为这个标头的全部内容。
2) 搜索由 q字符序列 识别的源文件,并将该指令替换为这个源文件的全部内容。可能退回至语法 (1) 并将 q字符序列 视为标头标识符。
3) 如果 (1) 和 (2) 都不匹配,记号序列 会经历宏替换。该指令在替换后会再次尝试匹配 (1) 和 (2)。
4) 检查是否可以包含一个标头或源文件。
5) 如果 (4) 不匹配,h记号序列 会经历宏替换。该指令在替换后会再次尝试匹配 (4)。
换行 | - | 换行字符 |
h字符序列 | - | 一个或多个 h字符 的序列,并且其中以下内容的出现受条件性支持:
|
h字符 | - | 源字符集 翻译字符集 除了换行符和 > 以外的任何成员 |
q字符序列 | - | 一个或多个 q字符 的序列,并且其中以下内容的出现受条件性支持:
|
q字符 | - | 源字符集 翻译字符集 除了换行符和 " 以外的任何成员 |
记号序列 | - | 一个或多个预处理记号的序列 |
字符串字面量 | - | 一个字符串字面量 |
h记号序列 | - | 一个或多个除了 > 以外的预处理记号的序列 |
1) 在一系列由实现定义的地点中搜索由 h字符序列 唯一识别的标头,并将该指令替换为这个标头的全部内容。由实现定义如何制指定这些地点和识别标头。2) 将该指令替换为由 q字符序列 识别的源文件的全部内容。所指名的源文件通过由实现定义的方式进行搜索。如果不支持这种搜索或者搜索失败,该指令按语法 (1) 重新处理,将原指令中包含的序列(包括大于号,如果存在)作为语法 (1) 中所需的序列。3) 该指令中 include
后面的预处理记号会按在正常文本中进行处理(即每个目前定义为宏名的标识符都会被替换为它的预处理记号替换列表)如果在所有替换都完成后生成的指令不匹配前面两种语法,那么行为未定义。将在一对预处理记号 < 和 > 之间或一对 " 字符之前的预处理记号序列合并为单个头名预处理记号的方法由实现定义。4) 搜索由 h字符序列 或 q字符序列 识别的标头或源文件,如同通过将该预处理记号序列作为语法 (3) 中的 记号序列 的方法进行搜索,但不会实施后续的宏展开。如果刚才的语法 (3) 指令不满足 #include
指令的语法要求,那么程序非良构。如果搜索成功,__has_include
表达式求值为 1,否则(搜索失败时)求值为 0。5) 只有在不匹配 (4) 才会选择此形式,此时预处理记号会按在正常文本中进行处理。
如果由 标头名(即
|
__has_include
可以在 #if 和 #elif 的表达式中展开。它被 #ifdef, #ifndef, #elifdef, #elifndef 和 defined 视为已定义的宏,但不能在其他任何地方使用。
语法 (1) 的意图是搜索由实现所掌控的文件。典型实现仅搜索标准包含目录。这些标准包含目录中隐含地包含标准 C++ 库和标准 C 库。用户通常能通过编译器选项来控制标准包含目录。
语法 (2) 的意图是搜索不被实现所掌控的文件。典型实现首先于当前文件所在的目录搜索,然后退回使用语法 (1)。
包含一个文件时,它将经过翻译阶段 1-4 的处理,这可能递归地包含嵌套 #include
指令的展开,直到一个由实现定义的嵌套限制。为避免(可能传递性地)重复包含相同文件,和由文件包含自身造成的无限递归,通常使用头文件防护:整个头文件被包装在下列结构中
声明:以上是华未云整理的全部内容。本站资源来自及互联网公开收集,仅限学习交流使用,请遵循相关法律法规,如有侵权争议、不妥之处请联系本站删除处理!