C/C++程序的编译过程
我们拿到一个.c或者是.cpp源文件,它是怎么样一步步的变化成一个机器可执行文件的呢?程序的一般编译流程主要包括四大部分:预处理、编译、汇编和链接。下面讲解这四步的具体工作,带你了解源文件到可执行文件是怎样生成的。
编译过程
- 1. 预处理(Preprocess)
- 2. 编译(Compilation)
- 3. 汇编(Assemoly)
- 4. 链接(Linking)
1. 预处理(Preprocess)
这一步由预处理器完成,对源程序中的伪指令(以#开头的指令)和特殊符号进行处理,伪指令包括宏定义指令、条件编译指令和头文件中包含的指令。这一步的主要工作包括以下内容:
- 将所有的#define删除,并将宏定义进行宏展开;
- 处理所有条件编译指令,如#if、#ifdef、#ifndef、#else、#elif、#endif等;
- 处理 #include预编译指令,将被包含的头文件内容插入该预编译指令的位置,如果是多重包含的话会递归执行;
- 处理其他宏指令,包括#error、#warning、#line、#pragma;
- 处理所有注释(C++的//,C语言的/**/),一般会用一个空格来代替连续的注释;
- 添加行号和文件标识,以便于编译时编译器产生调试用的行号信息及编译时产生编译错误和警告时可以把行号打印出来;
- 保留所有的#pragma编译器指令;
- 处理预定义的宏:如__DATE__、__FILE__等;
- 处理三元符:比如会将??=替换为#,将??/替换成\等(对于键盘不提供#等输入的情况,可能会用到三元符,可以直接忽略这一条);
2. 编译(Compilation)
这一步由编译器完成,对预处理后的文件进行词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件。
- 词法分析:词法分析是编译过程的第一个阶段,这个阶段的任务可以看成是从左到右一个字符一个字符地读入源程序,从中识别出一个个单词符号,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。上述读入源程序的过程和识别符号的任务通过词法分析程序实现,词法分析整个过程依据的是语言的词法规则。词法分析程序的输出通常是一个二元组,即单词种别和单词自身的值。词法分析程序可以使用lex等工具自动生成。
- 语法分析:语法分析是编译过程的一个逻辑阶段,此阶段的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等。语法分析程序判断源程序在结构上是否正确。
- 语义分析:语义分析是编译过程的一个逻辑阶段,语义是解释控制信息每个部分的意义,它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应,此阶段的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查,语义分析将审查类型并报告错误。也就是说,语义分析结合上下文推导出语句真正的含义。
3. 汇编(Assemoly)
由汇编器完成,将汇编代码转变成机器可执行的二进制代码(机器码),并生成目标文件。之所以要经过预处理、编译、汇编这么一系列步骤才生成目标文件,是因为在每一阶段都有相应的优化技术,只有在每个阶段分别优化并生成最为高效的机器指令才能达到最大的优化效果,如果一步到位直接从源程序生成目标文件,可能就会失去很多代码优化的机会。
4. 链接(Linking)
由链接器完成,主要解决多个文件之间符号引用的问题,即symbol resolution。编译时编译器只对单个文件进行处理,如果该文件里面需要引用到其他文件中的符号,比如全局变量或者调用了某个库函数中的函数,那么这时候,在这个文件中该符号的地址是没法确定的,只能由链接器把所有的目标文件链接到一起才能确定最终的地址,并生成最终的可执行文件。无论采用静态链接还是动态链接,都会生成一个可以在计算机上执行的可执行程序。
C/C++程序的编译过程相关推荐
- gcc编译c文件_Linux下C语言程序的编译过程
Linux下C语言程序的编译过程 使用gcc编译程序时,编译工程分为4个阶段: (1)预处理:(Pre-Processing) (2)编译:(Compiling) (3)汇编:(Assembling) ...
- 从helloworld回顾程序的编译过程之一
计算机中所有的文件都是以01数字形式保存的,我们常见的程序文件也是如此,以常见的入门程序Hello.c为例,其代码为代码段1所示: 代码段1 //hello.c #include <stdio. ...
- WPF 程序的编译过程
基于 Sdk 的项目进行编译的时候,会使用 Sdk 中附带的 props 文件和 targets 文件对项目进行编译.Microsoft.NET.Sdk.WindowsDesktop 的 Sdk 包含 ...
- 五分钟带你了解!Java程序的编译过程
Java程序的编译过程 Java 语言的「编译期」其实是一段「不确定」的操作过程.因为它可能是一个前端编译器(如 Javac)把 *.java 文件编译成 *.class 文件的过程:也可能是程序运行 ...
- C语言程序makefile编译过程
C语言程序makefile编译过程 2022-0111 blog_010 makefile是一些大型linux下开发的项目经常会用到的编译脚本: 可以将makefile理解为类似shell一样的脚本语 ...
- 开发日记-20190903 关键词 C程序gcc编译过程
感觉挺茫然的,很多大学期间应该知道的事情,直到工作了一年了,自己才渐渐地意识到自己想要知道,要是大学期间能有人能帮助我,或许我,真的不会这么茫然吧,真的,真的.不过我也知道后悔过去,是一件多么愚蠢的事 ...
- 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程
一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...
- java程序编译_Java程序的编译过程
Java的编译期是一个模糊的概念,需要具体分析. 将 *.java文件转为 *.class的过程称为编译器的前端(前端编译).例如:JDK的javac编译器. 把字节码( *.class文件) 转变为 ...
- 一个C程序的编译过程(Linux环境下Gcc)
一 以下是C程序一般的编译过程: 从图中看到: 将编写的一个c程序(源代码 )转换成可以在硬件上运行的程序(可执行代码 ),需要进行编译阶段 和链接这两个阶段. 其中, 1. 编译阶段先通过&qu ...
- 简单认识程序的编译过程
文章目录 前言 程序的翻译环境 预编译 编译 汇编 链接 前言 在ANSI C 的任何一种实现中,存在两个不同的环境: 第一种是编译环境,在这个环境下源代码被转换成可执行的机器指令. 第二种是执行环境 ...
最新文章
- Java I/O演进与Linux网络I/O模型
- java.lang.classnotfoundexception解决方法
- java安装_使用Java 9模块化来发布零依赖本机应用程序
- Python零碎知识(7):硬性出错
- 别指望在NativeWindow里添加Flex组件
- SpringMVC配置视图的直接映射view-controller命名空间
- springaop----springaop的使用(一)
- python2.7 threading RLock/Condition文档翻译 (RLock/Condition详解)
- windows7修改双系统启动项名称、先后顺序、等待时间
- three.js 求两个vector3 的夹角_初中数学:动点问题-阿氏圆最值模型(2),求PD-1/2PC的最大值...
- python socket编程(tcp/udp)
- 递归二叉树的序列打印
- The process cannot access the file '' because it is being used by another process.....
- RJ45转COM线序关系
- declaration of 'com.afollestad.materialdialogs.R$id' appears in /data/app/xxx/split_lib_slice_3_apk
- Sloth演示程序及源代码发布
- Jenkins平台搭建
- iOS开发打包上传报错ERROR ITMS-90096
- 二十、观音、文殊两位菩萨变态大比拼
- html5新增属性cookies,关于cookie的SameSite属性