【转载】C++编译过程
C++编译过程
C++ 编译过程
在介绍编译器之前,先简单地说一下 C++ 的编译过程,以便理解编译器的工作。
编译(compiling)并不意味着只创建仅仅一个可执行文件。创建一个可执行文件是一个多级过程,其中最重要的过程是预处理(preprocessing),编译(compliation)和链接(linking)。从源代码文件到一个可执行文件的整个过程,最好的说法是 build(中文翻译的话,有叫生成,有叫编译链接,也有叫构建)。compiling 仅仅是 build 过程的一部分,但你经常会碰到许多人把 compile 指代整个过程。通常情况下,你不需要为这几个过程运行单独的命令,编译器自己会调用,如预处理器。
2.1 预处理
build 过程的第一步就是编译器运行 C 预处理器,目的是对代码文件进行文本上的处理。它会处理头文件包含指令(#include),条件编译指令(#ifdef……#endif)和宏(#define),这些指令叫做预处理指令,都以井字符 # 开头。编译器本身是绝对看不到这些预处理指令的。
比如:
#include <iostream>
这句代码会告诉预处理指令,要把 iostream 的文件内容抓去到当前文件,你每包含一个头文件,它就会把这个头文件的内容粘贴到这个文件中,然后把 #include 指令移除。
#define MY_NAME "Alex"
宏就是一个被其它内容(可能比较复杂)替换掉的字符串内容,此时预处理器会把下面的代码:
cout << "Hello" << MY_NAME << endl;
展开成:
cout << "Hello" << "Alex" << endl;
由于预处理器在编译器之前处理代码,它也可以用来移除代码——有时,你会要在代码里执行某些测试代码。你可以告诉预处理器,如果定义了某个宏,则包含某些代码。然后,如果你想执行这个代码,就定义这个宏,否则就移除掉这个宏的定义。
#include <iostream>
#define DEBUG using namespace std; int main() {
int x;
int y;
cout << "Enter value for x: ";
cin >> x;
cout << "Enter value for y: ";
cin >> y;
x *= y; #ifdef DEBUG
cout << "x: " << x << '\n' << "y: "<< y;
#endif
}
如果你不想执行变量的打印,那么只需简单注释掉 #define DEBUG 就行。
同样地,你也可以用 #ifndef 来改变条件——如果没有定义……这个方法通常用在引入多个头文件的时候。
2.2 编译
编译意味着把一个源文件(.cpp)转变成一个对象文件(object,.o 或 .obj)。
一个对象文件会把你程序里的每一个函数,封装成一个计算机处理器能理解的形式——机器指令(machine language instructions)。每一个源文件都是单独编译过的,即对象文件包含的机器代码都是编译过的源代码。比如,你有三个源文件,经过编译,生成了三个对象文件,每一个对象文件都包含了各自对应的机器代码。
但你还不能运行它们,这时候,就需要链接器了。
2.3 链接
链接(Linking),是把一堆对象文件和库(有时也可能仅仅是一个对象文件,但也需要链接)创建成一个单独的可执行文件(比如 .exe 或 .dll)。
链接器通过一种适当的格式创建一个可执行的文件,并传递每个独立的对象文件内容到一个可执行的结果。链接器也处理含有对象文件源代码之外的其它函数的引用,比如 C++ 标准库里的函数。当你调用了一个 C++ 标准库的函数,如 cout << “Hi”,你就在使用一个自己代码中没有定义的函数,它被定义在一个相关的对象文件中,但这是由编译器提供的,并不属于你。在编译时,编译器知道这个函数是有效的,因为你引出了 iostream 头文件,但由于这个函数不是 cpp 文件的一部分,编译器就会在调用树(call tree)留下一个存根(stub),链接器会遍历对象文件,针对每一个存根,它会找到正确的函数地址,然后从已链接过的其它对象文件中,用正确的地址替换掉对应的存根。
这个过程有时也叫做修正(fixup)。当你把你的程序分离成多个源文件时,你就会利用链接器来修正所有在源文件中调用过的函数。如果链接器找不到这个函数的位置,它就会生成一个 undefined function error,即便代码被编译器通过了,也不意味着代码是正确的。链接器是首先以全局的视角来探测这种错误的。
【转载】C++编译过程的更多相关文章
- Hive SQL的编译过程[转载自https://tech.meituan.com/hive-sql-to-mapreduce.html]
https://tech.meituan.com/hive-sql-to-mapreduce.html Hive是基于Hadoop的一个数据仓库系统,在各大公司都有广泛的应用.美团数据仓库也是基于Hi ...
- 关于一个程序的编译过程 zkjg面试
http://blog.csdn.net/gengyichao/article/details/6544266 一 以下是C程序一般的编译过程: 从图中看到: 将编写的一个c程序(源代码 )转换成可以 ...
- C/C++编译过程理解【转】
转载自:http://www.cppblog.com/woaidongmao/archive/2008/11/07/66254.aspx 今天,通过自己的努力终于对C/C++的编译过程有了个粗略的了解 ...
- Android编译过程详解(一)
Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...
- 英蓓特Mars board的android4.0.3源码编译过程
英蓓特Mars board的android4.0.3源码编译过程 作者:StephenZhu(大桥++) 2013年8月22日 若要转载,请注明出处 一.编译环境搭建及要点: 1. 虚拟机软件virt ...
- Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)
下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...
- FFmpeg在Linux下安装编译过程
转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52402759 今天介绍下FFmpeg在Linux下 ...
- (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正
@author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ 说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...
- (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)
@author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ 说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...
随机推荐
- Linux(一)
1.简单命令 1.1 ls指令 语法1:#ls [路径] 表示列出指定路径下的文件夹和文件的名字,如果路径没有指定则列出当前路径下的(lis ...
- 使用 mitmdump 进行 selenium webDriver绕过网站反爬服务的方法 pdd某宝 可用
安装: pip install mitmproxy 新建一个脚本 脚本代码: from mitmproxy import ctx injected_javascript = ''' // over ...
- ES6中常用的小技巧,用了事半功倍哦
ES6中常用的小技巧,如果能在实际项目中能使用到,必定事半功倍: 1. 强制要求参数 ES6提供了默认参数值机制,允许你为参数设置默认值,防止在函数被调用时没有传入这些参数. 在下面的例子中,我们写了 ...
- 前端开发规范:3-CSS
尽量使用缩写属性 border-top-style: none; font-family: palatino, georgia, serif; font-size: 100%; line-height ...
- window 操作
忘记密码:https://jingyan.baidu.com/article/066074d6762a59c3c21cb0f9.html
- sql server日期转换为dd-mon-yyyy和dd-MMM-yyyy这样的英文月份格式(27-Aug-2019)
脚本: /* 功能:sql server日期转换为dd-mon-yyyy和dd-MMM-yyyy这样的格式 示例:27-Aug-2019 作者:zhang502219048 脚本来源:https:// ...
- 用python暴力破解压缩文件并不是万能,至少这个场景我告诉你密码你用代码也破解不了
看到论坛上各种贴子写用python进行暴力破解的文章,于是自己也想去尝试一下,不试不知道,一试吓一跳,真的就像那句有名的”python由入门到放弃“,把论坛上别人的脚本全部自己敲一遍,运行不报错,但也 ...
- 【搬了一套别人的cf】
自己打了一堆没保存瞬间全没了.... 没有继续写的欲望 https://www.cnblogs.com/tea-egg/p/11664350.html
- react后台项目开发(一)
1. 项目开发准备 描述项目 技术选型 api 接口(4部分:3请求{url,请求方式,请求参数格式}, 1响应数据格式)/ 接口文档/ 测试接口 2. 启动项目开发 使用react脚手架创建项目 开 ...
- 第04组 Beta冲刺(2/4)
队名:斗地组 组长博客:地址 作业博客:Beta冲刺(2/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.分配展示任务 2.收集各个组员的进度 3.写博客 展示GitHub当日代码/文档 ...