C语言编译过程详解

  • Post author:
  • Post category:其他


C语言编译过程主要由四个步骤组成:预处理、编译、汇编、链接,最后得到一个可执行程序,在Unix/Linux平台上一般显示后缀为.out,在Windows上显示后缀为.exe,那在生成可执行文件的过程中编译器到底做了什么呢?一个.c文件是怎么一步步变成可执行文件?

  1. 预处理

  • 包含的头文件替换成对应的函数声明

  • 宏定义的展开,进行字符串的替换

  • 处理条件编译指令,如#ifdef/#else/#ifndef/#endif等

  • 删除代码中的注释

  • 文件添加行号和标识

新建test.c,添加以下内容

由图1可看出.c生成.i文件大小有17k,那为什么生成的.i文件比原文件大这么多?

图1

我们可以粗略看下.i文件里的内容,如图2,几乎都是一些函数声明,宏定义被替换成对应字符串

图2

  1. 编译

编译实质就是将高级语言转换成汇编语言,由.i 文件到.s文件的过程。具体主要做了以下一些事:

  • 语法分析,检测程序中是否存在语法错误就是在这个阶段进行的

  • 将源码翻译成汇编代码

  • 对代码进行优化

gcc -S test.i -o test.s 生成对应汇编代码,具体内容图3

图3

  1. 汇编

汇编的过程是把生成的汇编代码转换成机器码,即.s 到 .o的过程。

gcc -c test.s -o test.o 生成test.o文件,Windows下对应.obj文件,其中的内容是人看不懂的,只能看到一些系统内存空间的分布信息

图4

  1. 链接

在链接之前的.o文件还不能直接运行,需要将二进制文件所用到的外部库绑定才能正常运行

gcc -c test.o -o test 由.o最终生成可执行文件,查看test.o 和 test 的文件属性,如图5所示,可看出test是一个可执行的文件,动态链接了一些库文件,而test.o是一个可重定位的文件(包含了代码与数据,可以用来链接成可执行文件或共享目标文件,如目标文件与静态链接库)

图5

链接分为静态链接和动态链接:

  • 静态链接:在编译阶段把使用到的库链接到可执行文件,生成的文件较大,但执行速度快,不需要寻找链接库内容

  • 动态链接:在链接阶段只是添加一些使用库的描述信息,在程序运行时,再从系统把相应的动态库加载到内存,可执行文件小,但执行速度相对静态链接较慢,要在内存查找链接库内容

如有错误,欢迎指出!



版权声明:本文为qm_mq原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。