深入理解Compiler对C/C++程序的编译流程

1 编译器的工作过程:

       1.预处理阶段(头文件的编译)

     2.词法与语法分析阶段 (语法检查)

  3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件 (.obj文件)

  4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息。(生成.exe文件)

Example

  #include <stdio.h>
  #include "mytest.h"

  int main(int argc,char **argv)
  { 
    test = 25;
    printf("test.................%d\n",test);

  mytest.h头文件内容如下:

  int test;

 

1.预处理阶段:编译器以C文件作为一个单元,首先读C文件,引入第一行第二行的头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将这些东西和当前C文件做累和,形成一个‘’中间.c文件"(包含原.c和引用的.h文件)。

2. 编译阶段:形成“中间.c文件”后,test变量就变成了这个文件中的一个全局变量,此时编译器将“中间.c文件”的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件。

3.连接阶段:将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将目标文件中的二进制码按一定的规范整合到一个文件中,最终形成可执行文件exe。

 

2、.c文件与 .h文件各写什么内容?为何要分 .c和.h文件呢?

     .h文件是头文件,内含函数声明、宏定义、结构体定义等内容。.c文件是程序文件,内含函数实现,变量定义等内容。

      这样分开写成两个文件是一个良好的编程风格,并无实际意义。

 

3、动态编译和静态编译

    动态编译: 上述直接引用是动态编译。

    静态编译: 基本所有的C/C++编译器都支持一种链接方式被称为Static Link,即所谓静态链接。在这种方式下,头文件(.h文件), 以及他们对应的实现文件(.cpp文件),编译程序会将其编译为静态的库文件(.lib文件)。在随后的代码重用过程中,我们只需要引用相应的头文件(.h)和相应的库文件(.lib)即可。

  相对动态方式而言,静态方式的好处是实现代码的隐蔽性,即C++中提倡的"接口对外,实现代码不可见"。有利于库文件的转发.

 

 

 

tips.

C语言文件后缀必须小写.c,否则编译器gcc会认为为c++文件。 

 

上一篇:Yii框架的原代码


下一篇:webpack 源码解析一之启航