C++编译和链接详解

来源:互联网 发布:康师傅免流量软件 编辑:程序博客网 时间:2024/06/11 03:30

转自 http://blog.csdn.net/tomtestingresearch/article/details/6053470

1、 编译器和链接器

        C++调用gcc编译命令进行编译(不同编译器有所不同),调用link命令进行链接。例如:

              gcc 1.cpp -o 1.o
             gcc 2.cpp -o 2.o
             gcc 3.cpp -o 3.o

       生成三个文件1.o,2.o以及3.o。然后调用link命令:

       link 1.o 2.o 3.o -o App.exe

       生成可执行程序。

2、 C++编译链接分析

   1) 编译成目标文件

      编译:编译器对源代码进行编译,是将以文本形式存在的源代码翻译为机器语言形式的目标文件的过程。

     编译单元:对于C++来说,每一个cpp文件就是一个编译单元。从之前的编译过程的演示可以看出,各个编译单元之间是互相不可知的。
    目标文件:由编译所生成的文件,以机器码的形式包含了编译单元里所有的代码和数据,以及一些其他的信息。、

2) 目标文件

     每一个目标文件除了拥有自己的数据和二进制代码外,还提供了三个表:未解决符号表、导出符号表和地址重定向表。

    未解决符号表提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。
    导出符号表提供了本编译单元具有定义,并且愿意提供给其他编译单元使用的符号及其地址。
    地址重定向表提供了本编译单元所有对自身地址的引用的记录。

3) 目标文件的链接

     链接器进行链接的时候,首先决定各个目标文件在最终可执行文件里的位置。然后访问所有目标文件的地址重定向表,对其中记录的地址进行重定向(即加上该编译单元实际在可执行文件里的起始地址)。然后遍历所有目标文件的未解决符号表,并且在所有的导出符号表里查找匹配的符号,并在未解决符号表中所记录的位置上填写实际的地址(也要加上拥有该符号定义的编译单元实际在可执行文件里的起始地址)。最后把所有的目标文件的内容写在各自的位置上,再作一些别的工作,一个可执行文件就链接完成了。

3、 C++常用情景分析

1) extern

   编译器将extern声明的变量置入未解决符号表中,而不置入导出符号表中。(外部链接)

2)static

   编译器将static声明的全局变量既不置入未解决符号表中,也不置入导出符号表中。(内部链接)因此别的编译单元无法使用。

3)普通变量函数

普通变量及函数被置入导出符号表中。