翻译阶段 (Phases of translation)
C 语言的编译器处理代码生成程序的过程,可以分为以下 8 个步骤,称为翻译阶段:
实现定义
在编译器的实现中,可以按需组合或者以不同方式进行这些步骤,但行为必须和这些步骤描述的一致。
1. 八个阶段的语义顺序
- 将源文件映射到源字符集并识别行结束。
- 删除反斜杠加换行形成的续行。
- 把源文件分解为预处理记号与空白序列,并把注释替换为空格。
- 执行预处理指令,展开宏并处理
#include与条件编译。 - 将字符常量与字符串字面量中的转义序列、通用字符名映射到执行字符集。
- 连接相邻字符串字面量。
- 把记号流翻译为翻译单元,完成语法语义分析并生成目标代码。
- 链接各翻译单元与库,解析外部符号,形成最终程序映像。
2. 工程含义
翻译阶段解释了三个常见现象:第一,宏替换先于语义分析,所以宏更像“记号替换”;第二,头文件不是独立编译单元,而是被插入包含它的源文件;第三,字符串字面量自动拼接是语言规则,不是编译器私有技巧。
c
#include <stdio.h>
#define APP_NAME "Mdr"
#define APP_VER " C23"
int main(void) {
puts(APP_NAME APP_VER);
return 0;
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
可能的输出(示例):
bash
<输出与输入或平台相关,请以实际运行为准>
上例中 APP_NAME APP_VER 会在翻译阶段 6 连接为一个字符串字面量,再进入后续语义阶段。掌握这一点,调试宏问题会清晰很多。