翻译阶段
编译器如同下列阶段以此准确顺序发生一般处理 C 源文件。实际实现可以组合,或以不同方式处理这些动作,只要行为相同。
阶段 1
- 源字符集是包含作为单字节子集的基本源字符集的多字节字符集,后者由以下 96 个字符组成:
阶段 2
阶段 3
若已经分析输入为到给定字符为止的预处理记号,则通常将能构成一个预处理记号的最长字符序列处理成下个预处理记号,即这会导致后继分析失败。这常被称为最大吞噬 (maximal munch) 。
int foo = 1; int bar = 0xE+foo; // 错误:非法的预处理数字 0xE+foo int baz = 0xE + foo; // OK int quux = bar+++++baz; // 错误: bar++ ++ +baz ,而非 bar++ + ++baz 。
最大吞噬规则的单独例外是:
- 头文件名预处理记号仅在
#include
指令中和#pragma
指令中的实现定义位置形成。
#define MACRO_1 1 #define MACRO_2 2 #define MACRO_3 3 #define MACRO_EXPR (MACRO_1 <MACRO_2> MACRO_3) // OK : <MACRO_2> 不是头文件名
阶段 4
阶段 5
注意:某些实现中,能以命令行选项控制此阶段所进行的转换: gcc 和 clang 用 -finput-charset 指定源字符集的编码,用 -fexec-charset 和 -fwide-exec-charset 指定无编码前缀的 (C11 起)字符串字面量和字符常量中的执行字符集的编码。
阶段 6
连接相邻的字符串字面量。
阶段 7
发生编译:按照语法和语义分析记号,并将它们翻译成翻译单元。
阶段 8
发生链接:将翻译单元和满足外部引用所需的库组件到汇集成程序映像,它含有在其执行环境(操作系统)中执行所需的信息。
引用
- C11 标准(ISO/IEC 9899:2011):
-
- 5.1.1.2 Translation phases (第 10-11 页)
-
- 5.2.1 Character sets (第 22-24 页)
-
- 6.4 Lexical elements (第 57-75 页)
- C99 标准(ISO/IEC 9899:1999):
-
- 5.1.1.2 Translation phases (第 9-10 页)
-
- 5.2.1 Character sets (第 17-19 页)
-
- 6.4 Lexical elements (第 49-66 页)
- C89/C90 标准(ISO/IEC 9899:1990):
-
- 2.1.1.2 Translation phases
-
- 2.2.1 Character sets
-
- 3.1 Lexical elements