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++编译过程的更多相关文章

  1. Hive SQL的编译过程[转载自https://tech.meituan.com/hive-sql-to-mapreduce.html]

    https://tech.meituan.com/hive-sql-to-mapreduce.html Hive是基于Hadoop的一个数据仓库系统,在各大公司都有广泛的应用.美团数据仓库也是基于Hi ...

  2. 关于一个程序的编译过程 zkjg面试

    http://blog.csdn.net/gengyichao/article/details/6544266 一 以下是C程序一般的编译过程: 从图中看到: 将编写的一个c程序(源代码 )转换成可以 ...

  3. C/C++编译过程理解【转】

    转载自:http://www.cppblog.com/woaidongmao/archive/2008/11/07/66254.aspx 今天,通过自己的努力终于对C/C++的编译过程有了个粗略的了解 ...

  4. Android编译过程详解(一)

    Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...

  5. 英蓓特Mars board的android4.0.3源码编译过程

    英蓓特Mars board的android4.0.3源码编译过程 作者:StephenZhu(大桥++) 2013年8月22日 若要转载,请注明出处 一.编译环境搭建及要点: 1. 虚拟机软件virt ...

  6. 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 ...

  7. FFmpeg在Linux下安装编译过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52402759 今天介绍下FFmpeg在Linux下 ...

  8. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正

    @author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...

  9. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)

    @author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...

随机推荐

  1. 中移动物联手机端APP软件

    https://open.iot.10086.cn/doc/book/device-develop/multpro/sdk-doc-tool/APP.html

  2. EggJS接口开发

    需求 随着Nodejs的普及,前端开发的开发场景基本可以贯穿界面交互到数据存储,无缝实现全栈开发.最近在实现一个内部项目管理工具的时候,就尝试了一把接口和数据库开发. 什么是Egg.js Egg.js ...

  3. 通过Ajax的访问zuul的跨域问题解决方案

    刚开始在使用jqueryajax跨域请求zuul网关时,在后台发现一直拿不到前台请求的json数据,而前台也一直拿不到后台的响应数据.打开浏览器调试程序发现,本身ajax的POST请求统一都变成了op ...

  4. idea使用maven中的tomcat插件开启服务出现java.net.BindException: Address already in use: JVM_Bind :8080错误原因

    [INFO] create webapp with contextPath: /maven_web 五月 11, 2019 6:05:26 下午 org.apache.coyote.AbstractP ...

  5. MVVM解析

    闲来无事看到了一个关于Vue的MVVM的简单讲解,觉得写得不错,做个分享. 文章地址 https://github.com/DMQ/mvvm 文章内容我就不贴出,比较简洁明了,我记录一下我的一些思考总 ...

  6. leaflet 结合 Echarts4 实现迁徙图(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  7. arcgis api 4.x for js 结合 Echarts4 实现散点图效果(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 4.x for js:esri 官网 api,里面详细的介绍 arcgis api 4.x 各个类 ...

  8. MongoDB用户验证和权限管理

    官方参考页面: https://docs.mongodb.com/v3.6/tutorial/enable-authentication/ https://docs.mongodb.com/v3.6/ ...

  9. Cocos2d-x3.0网络通信学习(一)

    配置:win7+Cocos2d-x.3.0+VS2012 摘要:建立基本的http通信并得到返回信息. 一.添加项目与编译库 1.添加头文件 在需要用到Http网络相关类的文件中加入头文件 #incl ...

  10. Python生成requirements.txt方法

    在查看别人的Python项目时,经常会看到一个requirements.txt文件,里面记录了当前程序的所有依赖包及版本号,其作用是用来在另一个环境上重新构建项目所需要的运行环境依赖. require ...