命名空间
变体
操作

预处理器

出自 cppreference.cn
< cpp
 
 
C++ 语言
通用主题
预处理器
注释
流程控制
条件执行语句
if
迭代语句(循环)
for
范围 for (C++11 起)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直至 C++17*)
noexcept 说明符 (C++11 起)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11 起)
auto (C++11 起)
constexpr (C++11 起)
consteval (C++20 起)
constinit (C++20 起)
存储期说明符
初始化
表达式
替用表示
字面量
布尔 - 整数 - 浮点
字符 - 字符串 - nullptr (C++11 起)
用户定义 (C++11 起)
工具
属性 (C++11 起)
类型
typedef 声明
类型别名声明 (C++11 起)
转型
内存分配
类特定的函数属性
虚函数
override 说明符 (C++11 起)  
final 说明符 (C++11 起)
explicit (C++11 起)
static

特殊成员函数
模板
模板特化
形参包 (C++11 起)
杂项
 
 

预处理器在翻译阶段 4,编译之前执行。预处理的结果是单个文件,然后将其传递给实际的编译器。

目录

[[编辑]] 指令

预处理指令控制预处理器的行为。每个指令占用一行,并具有以下格式

  • # 字符。
  • 一个序列,包含:
  • 一个标准定义的指令名称(列于下方),后跟相应的参数,或
  • 一个或多个预处理记号,其中起始记号不是标准定义的指令名称,在这种情况下,指令是有条件支持的,具有实现定义的语义 (例如,常见的非标准扩展是 #warning 指令,它在编译期间发出用户定义的消息)(截至 C++23),或
  • 什么都没有,在这种情况下,指令不起作用。
  • 换行符。

模块和导入指令也是预处理指令。

(C++20 起)

预处理指令不得来自宏展开。

#define EMPTY
EMPTY   #   include <file.h> // not a preprocessing directive

[[编辑]] 功能

预处理器具有源文件翻译功能:

  • 有条件地 编译源文件的部分内容(由指令 #if#ifdef#ifndef#else#elif#elifdef#elifndef(C++23 起)#endif 控制)。
  • 替换 文本宏,同时可能连接或引用标识符(由指令 #define#undef 以及运算符 ### 控制)。
  • 包含 其他文件(由指令 #include 控制,并使用 __has_include(C++17 起) 检查)。
  • 引起 错误 警告(C++23 起)(分别由指令 #error#warning 控制(C++23 起))。

预处理器的以下方面可以控制:

  • 实现定义 的行为(由指令 #pragma 和运算符 _Pragma(C++11 起) 控制)。此外,一些编译器(在不同程度上)支持运算符 __pragma 作为非标准扩展。
  • 可供预处理器使用的文件名和行信息(由指令 #line 控制)。

[[编辑]] 缺陷报告

以下行为变更缺陷报告被追溯应用到先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
CWG 2001 C++98 使用非标准定义指令的行为不明确 变为有条件支持

[[编辑]] 参见

C++ 文档 关于 预定义宏符号
C++ 文档 关于 宏符号索引
C 文档 关于 预处理器