通过 GCC 查看预处理(宏展开)之后的实际代码

2019-11-19 / C

预处理 命令可以改变程序设计环境,提高编程效率,它们并不是 C 语言本身的组成部分,不能直接对 它们进行编译,必须在对程序进行编译之前,先对程序中这些特殊的命令进行“预处理” 。经过预处理后,程序就不再包括预处理命令了,最后再由编译程序对 预处理 之后的源程序进行 编译 处理,得到可供执行的目标代码。C 语言提供的预处理功能有三种,分别为 宏定义、文件包含和条件编译。

如果想知道预处理后最终的代码,可以通过 GCC 来查看。

0x01 测试用的代码

  1. 文件名为 main.c
#define MAXN 100

int main() {
    int a[MAXN];
    for (int i = 0; i < MAXN; i++) {
        scanf("%d", &a[i]);
    }
    return 0;
}

0x02 用 gcc 命令对测试用的代码进行预处理(不编译)

  1. 通过以下指令对 main.c 文件进行预处理,并输出到 test.log 中。

    gcc -E main.c -o test.log
    
  2. test.log 中的内容

# 1 "main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 362 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.c" 2


int main() {
    int a[100];
    for (int i = 0; i < 100; i++) {
        scanf("%d", &a[i]);
    }
    return 0;
}
能看到 `main.c` 源文件中的 `MAXN` 都被替换成了 `100`

0x03 来点稍微复杂的预处理看看

  1. 源程序文件名为 main.c
#define MAXN 100
#define FOR(id,size) for(int id = 0; id < (size); id++)
#define MUL(i,j) i*j
#define MUL2(i,j) (i)*(j)

int main() {
    int a[MAXN];
    FOR(i, MAXN) {
        scanf("%d", &a[i]);
    }
    MUL(2,3+4);
    MUL2(2,3+4);
    return 0;
}
  1. 接下来看看预处理之后的源代码
# 1 "main.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 362 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.c" 2





int main() {
    int a[100];
    for(int i = 0; i < (100); i++) {
        scanf("%d", &a[i]);
    }
    2*3+4;
    (2)*(3+4);
    return 0;
}
  1. 分析: 这里我们发现,预处理其实就是对 C 语言的源程序进行替换。预处理只是编译时的东西,而不是运行时的。而且这里仅仅是对文本进行替换,就算程序不能通过编译,也可以通过预处理的。