编译链接(1)

前言

本文介绍了简单的介绍gcc编译一个程序的时候做了什么

正文

一个例子

********fn1.c************
#include<iostream>
void fn1(){        //定义了一个函数
    std::cout<<"this is fn1"<<std::endl;
}
********main.c************
void fn1();       //声明了一个函数

int main(){
    fn1();
}

首先来看一个例子,有两个文件内容如上,fn1.c中定义了一个函数fn1(),而main.c中只是声明了fn1()是一个函数,有时我们一般会用如下方式编译, 然后目录下就多了一个可执行文件a.out

g++ main.c fn1.c

但这里封装的太好导致隐藏了很多细节,它实际工作如下,包含了编译期和链接期

g++ -c fn1.c   //编译期,生成fn1.o
g++ -c main.c  //编译期,生成main.o
g++ -o a.out fn1.o main.o //链接期, 搜索fn1.o和main.o文件中的符号,维护一张符号表,为只有声明还未没有定义的符号找到其定义的地方,这步就叫做链接

关于链接

多个.o文件(又称为目标文件)进行链接的时候,这些文件中携带了自己的符号信息,链接器首先会通过这些信息去维护符号表,而这个维护的过程中会经常出现一些符号重定义的问题,就是因为不同的目标文件中有同名的符号;
在链接器维护完这张符号表之后,就可以通过它对.o文件中的声明但是未定义的符号进行链接操作,如果没找到,就会报找不到符号的错;

posted @ 2019-12-22 16:35  woder  阅读(237)  评论(0编辑  收藏  举报