在编码完成之后,编译之前,还存在一个阶段,称之为预处理 。所谓的预处理,其实是相对于下一个阶段“编译”而言的,在编译之前,预先处理一下源代码,既有点像是编码,又有点像是编译,是一个中间阶段。
预处理是 C/C++ 程序独有的阶段,其他编程语言都没有,这也算是 C/C++ 语言的一个特色了。
在这个阶段,发挥作用的是预处理器(Pre-processor)。它的输入是编码阶段产生的源码文件,输出是经过“预处理”的源码文件。“预处理”的目的是文字替换,用到的就是我们熟悉的各种预处理指令,比如 #include、#define、#if 等,实现“预处理编程”。
# // 预处理空行
#if __linux__ // 预处理检查宏是否存在
# define HAS_LINUX 1 // 宏定义,有缩进
#endif // 预处理条件语句结束
# // 预处理空行
不编译,只输出预处理之后的源码 g++ test03.cpp -E -o a.cxx
预处理指令
#include
staticuint32_t calc_table[] = {
# include "calc_values.inc" // 非常大的一个数组,细节被隐藏
};
// file: calc_values.inc
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
...
#ifndef / #ifdef / #endif
#define / #undef
#define ngx_tolower(c) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
#define ngx_toupper(c) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
#undef ngx_tolower // 取消宏定义
#if / #elif / #else / #endif
#if 0 // 0即禁用下面的代码,1则是启用
... // 任意的代码
#endif // 预处理结束
#if 1 // 1启用代码,用来强调下面代码的必要性
... // 任意的代码
#endif // 预处理结束
# g++
g++ -E -dM - < /dev/null