C++编译理解


c++编译器工作原理

我们写程序通常情况要考虑如何将文本转化为可执行文件,在这里编译器所执行的工作就是完成compliling和linking。而c++编译器所要做的就是把文本变为中继格式,也就是obj文件 ,然后obj文件 会传入linker中,linker就会发挥它的作用。

compiling过程中先预处理代码,所有预处理语句会被评估,预处理后,会进入tokenizing(标记解释)和parsing(解析)阶段。 基本上结果就是创建某种叫做abstract syntax tree(抽象语法树),也就是我们代码的表达,编译器的工作也就是把代码转化为constant data(常数资料),要么就是instructions(指令),编译器创建了这样一个抽象语法树之后,就可以产生代码了,这个代码是执行器真正执行的机器码。接下来根据一个简单的例子来理解编译器工作的机制。

我们运行输出hello world的程序,会发现debug文件夹会自动生成与之同名的.exe可执行文件。在这里插入图片描述
我们打开下面的文件夹
在这里插入图片描述
会发现生成的有obj后缀文件,这里也就是编译器给每个cpp相当于也就是每个tanslation unit(编译单元),生成了obj文件。这里需要注意到c++这门编程语言根本不在乎文件,文件在c++根本也就不存在。只要我们告诉编译器进行编译的类型和规则即可。

下面我们新建一个math.cpp文件,内容很简单,为俩个数相乘,下面进行编译会发现生成obj文件,会发现这个文件很小。这是因为没有包含iosstream文件。
在这里插入图片描述
include的原理也很简单,将后面包含的文件预处理打开该文件,读取该文件中的所有内容并复制粘贴你写include的那个文档,
在这里插入图片描述
所以这样写成也是可以编译成功,因为Endbrace.h中包含了}。下面可以让编辑器输出一个文档,里面包含预处理后的结果。
在这里插入图片描述
设置如图所示。再次编译,我们会发现生成了math.i文件。
在这里插入图片描述
打开之后,我们发现写的#include “Endbrace.h”已经被替换为了}。接下来我们可以使用预处理语句来根据特定条件包含或者剔除代码。
在这里插入图片描述
这时候会发现代码没有变化。如果If后面的值改为0,就会发现代码中没有了这一部分。
在这里插入图片描述
如果更改为iosstream,再进行编译会发现出来以下内容。
在这里插入图片描述
所以生成的obj文件会很大。

编译过程之后完成就是链接相关方面的过程。链接就是把所有的obj文件整合到一起,生成相关的exe文件。
下面有个在头文件中很重要的东西,由于有时候由于错误原因会重复包含头文件,这种情况就会发生错误,比如:#include “b.h”中已经包含了#include “a.h” ,在另外一个头文件包含前俩个,如果不用预处理命令,就会发生错误,所以这个时候就需要`

ifndef XXXX

defineXXXX

…..

endif`

XXX的名称随意,每个头文件保持不一样,因为假如出现多次包含关系的时候,由于已经该定义,所以#ifndef条件为假,所以就不会出现错误了。


文章作者: WYW
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WYW !
评论
 上一篇
卫星工具箱 卫星工具箱
卫星通信工具箱该卫星工具箱用来模拟、分析和测试卫星通信系统和链路。卫星通信工具箱提供了基于标准的工具,用于设计,模拟和验证卫星通信系统和链接。该工具箱使您能够建模和可视化卫星轨道,并执行链接分析和访问计算。您还可以将物理层算法与RF组件和接
2022-07-10 WYW
下一篇 
Ros学习Day6 Ros学习Day6
1:功能包的创建这一节学习参数的编程和使用。首先创建这一讲所需要的功能包。输入指令:cd /catkin_ws/src catkin_create_pkg learning_parameter roscpp rospy std_srvs
2022-06-20
  目录