C++的编译与连接
编译器的任务是把我们人类通常能够读懂的文本形式的 C 语言文件转化成计算机能明白的目标文件。
1. 预编译
生成的仍然是.c文件
1)把"include"的文件拷贝到要编译的源文件中。
2)用实际值替代"define"的文本。
3)在调用宏的地方进行宏替换。
2. 编译
这个过程是用于生成汇编语言,.asm文件。
3. 生成目标文件
.o文件,包含了以下两项内容
- 代码:对应着 C 文件中函数的定义
- 数据:对应着 C 文件中全局变量的定义(对于一个已初始化的全局变量,它的初值也存于目标文件中)。
编译器会留个空白(blank),这个“空白”(我们也称之为“引用”(reference))拥有与之相关联的一个名字,但该名字对应的值还尚未可知。
链接器的任务是连接变量/函数的名字与变量/函数的定义,生成可执行文件。
如果不能连接,就会抛出external error
初始化变量已经提前赋予了某个特定的初值,这些值同时保存于目标文件和可执行文件中。当程序开始运行时,操作系统将这些值拷贝至内存中一块名为数据段(data segment)的区域;对未初始化变量,操作系统假设其初值均为0, 因此没有必要对这些值进行拷贝,操作系统保留一部分全为0内存空间,我们称其为 bss 段(bss segment)。
局部变量的生命周期只存在于程序运行之时,所以链接器无需处理。他们存储在栈或堆中,由于堆和栈在程序运行过程中都会动态地改变大小,通常的处理方式是让栈从一个方向向另一个方向增长,而堆则从另一端增长。
库:如果有很多不同的程序都需要做一些相同的操作(例如将输出打印到屏幕上,从硬盘读取文件等),那么所有相关的目标文件集合都统一存放在一个方便访问的地方,这个地方就称为库
静态库(static library),在Windows平台上,静态库的扩展名为 .LIB,可用 .LIB 工具生成。
缺点1:循环依赖。
从静态库中导入文件的粒度:如果某个特定符号的定义是必须的,那么包含该符号定义的整个目标文件(不是整个静态库)被导入。
库的处理顺序。链接器按命令行从左到右的顺序进行处理,只有前一个库处理结束了,才会继续处理下一个库。换句话说,如果后一个库中导入的目标文件依赖于前一个库中的某个符号,那么链接器将无法进行自动关联,导致链接失败。
缺点2:一旦程序完成静态链接后,代码就永久保持不变了,如果万一有人发现并修复了 printf 中的某个bug,那么所有使用了printf的程序都不得不重新链接才能应用上这个修复。
缺点3:所有可执行文件都要存储一份如printf,fopen这类常用函数的拷贝,将占用大量的硬盘空间。
共享库(Shared libraies),其扩展名在 Unix 系统中为 .so,在 Windows 系统中为 .dll,在Mac OS X系统中为 .dylib。
优点1:链接的粒度(the granularity of the link)。
如果程序中只引用了共享库里的某个符号(比如,只使用了 libc.so 库中的 printf),那么整个共享库都将映射到程序地址空间中,之后可自行解决相互引用问题。并且,库内的符号集中保存在一片连续的空间里。
优点2:链接完后改变的代码,在运行时会生效。
优点3:对于共享库,链接器没有必要将所有的符号都关联起来,而是贴上一个“我欠你(IOU)”这样的标签,直到程序真正运行时才对贴有这样标签的内容进行处理。
C++的编译与连接的更多相关文章
- gVim/Vim 一键编译、连接、运行 C/C++ 单文件
用于Gvim 或 Vim 配置文件的一键编译与运行函数(注:需要机器上安装了GCC才行) 本代码只加入了对C/C++的编译与运行,如果要加入其语言的可以参考此代码加入即可 同时,本代码加入了对Wind ...
- iOS_02_第一个C语言程序(理解编译、连接、运行)
一.开发工具的选择 1. 可以用来写代码的工具:记事本.ULtraEdit.Vim.Xcode等. 2. 选择XCode的原因:苹果公司官方提供的开发利器.简化开发的工程.有高亮显示功能. 3. 使用 ...
- C编译: 动态连接库 (.so文件)(转摘)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在“纸上谈兵: 算法与数据结构”中,我在每一篇都会有一个C程序,用于实现算法和数据 ...
- 如何使用MASM来编译、连接、调试汇编语言
先声明下,本人绝非大虾,也只是菜鸟一个,写此文的目的只是为了加深我对知识的理解罢了.好,进入正题.我是把masm解压后发在D盘中的一个叫masm的文件里,在masm文件里新建个记事本(记事本功能是很强 ...
- C编译: 动态连接库 (.so文件)
转自:http://www.cnblogs.com/vamei/archive/2013/04/04/2998850.html 在“纸上谈兵: 算法与数据结构”中,我在每一篇都会有一个C程序,用于实现 ...
- Keil C51编译及连接技术
主要介绍Keil C51的预处理方法如宏定义.常用的预处理指令及文件包含指令,C51编译库的选择及代码优化原理,C51与汇编混合编程的方法与实现以及超过64KB空间的地址分页方法的C51实现. 教学目 ...
- mtcp的快速编译(连接)
mtcp的快速编译 http://mos.kaist.edu/guide/config/03_build_mtcp.html 介绍DPDK中使用mtcp的文档 https://dpdksummit.c ...
- Makefile之编译运行连接库方法
LIBS+= -L $$PWD/../HKUnifyCamera_one/Debug -lHKUnifyCamera -luuid -Wl,-rpath=$$PWD/../HKUnifyCamera_ ...
- 【Linux下Hadoop-eclipse-plus-3.2.0】编译Hadoop连接eclipse的插件遇见的一系列错误,崩溃的操作
2019-09-02 23:35:22 前言:首先,我想吐槽下自己,居然花费了4到5个夜晚和中午的时间来做这件事情,直到刚才才顺利解决,我也挺佩服自己的! 我在这个过程中参考其他人的博客,非常感谢他们 ...
随机推荐
- 发邮件 文字+ 附件的方法(QQ or 网易 邮箱)
#coding:utf-8import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIME ...
- [UE4]多播代理
1. 第一种 DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FReceiveDelegateEvent, FString, Value1, FString, ...
- 2018ICPC网络赛(焦作站)K题题解
一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...
- chapter1 初识Go语言
1.1 语言简史 1.2 语言特性 I:自动垃圾回收 II:更丰富的内置类型 数组切片(Slice):是一种动态增长的数组. III:函数多返回值 func getName()(firstName, ...
- ExtJS的数据模型
给大家介绍一下ExtJS的组件模型. 常见的Ajax的开发流程: 1.定义URL,metod,params 2.开发后台 接收JSON/XML数据 返回JSON/XML数据 3.前台回调 4.显示到 ...
- C#中 ThreadStart和ParameterizedThreadStart区别
最主要区别: 1.Thread 是启动一个线程,但是没有参数. 2.ParameterThreadStart 线程可以接受一个输入参数 ThreadStart: ThreadStart这个委托定义为 ...
- Python预编译语句防止SQL注入
这个月太忙,最近不太太平,我的愿望是世界和平! ================================== 今天也在找python的预编译,早上写的sql是拼接来构成的.于是找了2篇文章,还 ...
- File处理
package com.cfets.ts.u.shchgateway.util; import java.io.BufferedInputStream; import java.io.Buffered ...
- 隐藏bat脚本运行时弹出的黑窗口,以隐藏进程在后台执行.
1.把这段代码写在前面@echo offif "%1"=="r" goto startif "%1"=="h" goto ...
- java8函数式编程(转载)
1. 概述 1.1 函数式编程简介 我们最常用的面向对象编程(Java)属于命令式编程(Imperative Programming)这种编程范式.常见的编程范式还有逻辑式编程(Logic Progr ...