编译链接(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文件中的声明但是未定义的符号进行链接操作,如果没找到,就会报找不到符号的错;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界