预编译 之 #展开

版权声明:本文为博主原创文章,转载请附上本文链接地址。from : https://blog.csdn.net/lovechris00 https://blog.csdn.net/lovechris00/article/details/81636500


创建C文件并使用GCC预编译为 .i文件

1、创建一个.c文件:hw0.c,写入如下的代码:

#include <stdio.h>

int main() {

    printf("Hello, World!");

    return 0;
}

2、使用 gcc 进行预编译

$ gcc -E hw0.c -o hw0.i

得到 hw0.i 文件。

gcc 命令:http://man.linuxde.net/gcc
-o:指定生成的输出文件;
-E:仅执行编译预处理;
-S:将C代码转换为汇编代码;
-wall:显示警告信息;
-c:仅执行编译操作,不进行连接操作。


3、使用 vi 查看该文件

$ vi /Users/administrator/MacOSExec/MSCommand0/MSCommand0/hw0.i 

这里写图片描述

会发现 #include <stdio.h> 没有了,取而代之的是很多很多的文件。这些文件是 stdio.h 的展开,还包含 stdio.h 中引用文件的展开。


我们都用过 #include#import, 这里的 # (读作 hash),被称为 行标记 ,告诉我们后面跟着的内容来自哪里。

本文中所做的事情是告诉预处理器将文件 stdio.h 中的内容插入到 #include 语句所在的位置。
因为 stdio.h 可能会包含其它的文件,所以这是一个递归的过程。


由于这样的递归插入过程很多,所以我们需要确保记住相关行号信息。
为了确保无误,预处理器在发生变更的地方插入以 # 开头的 行标记。

跟在 # 后面的数字是在源文件中的行号,而最后的数字是在新文件中的行号

# 411 "/usr/include/stdio.h" 3 4

回到刚才打开的文件,紧跟着的是系统头文件,或者是被看做为封装了 extern "C" 代码块的文件。


使用 Xcode 预编译

在 Xcode 中,可以通过这样的方式查看任意文件的预处理结果:Product -> Perform Action -> Preprocess

// Preprocessed output for hw0.c
// Generated at 8:18:00 下午 on 星期一, 八月 13, 2018
// Using Debug configuration, x86_64 architecture for MSCommand0 target of MSCommand0 project

# 1 "/Users/administrator/MacOSExec/MSCommand0/MSCommand0/hw0.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 342 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/Users/administrator/MacOSExec/MSCommand0/MSCommand0/hw0.c" 2








#pragma clang module import Darwin.C.stdio /* clang -E: implicit import for #include <stdio.h> */

int main() {

    printf("Hello, World!");

    return 0;
}

为什么内容会比上面少那么多呢?


参考:
- Mach-O 可执行文件
https://objccn.io/issue-6-3/

猜你喜欢

转载自blog.csdn.net/lovechris00/article/details/81636500
今日推荐