How does the compilation and linking process work?
The compilation of a C++ program involves three steps:
Preprocessing: the preprocessor takes a C++ source code file and deals with the
#include
s,#define
s and other preprocessor directives. The output of this step is a "pure" C++ file without pre-processor directives.Compilation: the compiler takes the pre-processor's output and produces an object file from it.
Linking: the linker takes the object files produced by the compiler and produces either a library or an executable file.
Preprocessing
The preprocessor handles the preprocessor directives, like #include
and #define
. It is agnostic of the syntax of C++, which is why it must be used with care.
It works on one C++ source file at a time by replacing #include
directives with the content of the respective files (which is usually just declarations), doing replacement of macros (#define
), and selecting different portions of text depending of #if
, #ifdef
and #ifndef
directives.
The preprocessor works on a stream of preprocessing tokens. Macro substitution is defined as replacing tokens with other tokens (the operator ##
enables merging two tokens when it makes sense).
After all this, the preprocessor produces a single output that is a stream of tokens resulting from the transformations described above. It also adds some special markers that tell the compiler where each line came from so that it can use those to produce sensible error messages.
Some errors can be produced at this stage with clever use of the #if
and #error
directives.
这里拓展开来说,直接实验验证,查看预编译文件就能发现真相;
1、获取预编译文件(.i)
vs2015设置
2、整体编译一波,单个文件编译不了
3、到这个目录下拿到.i文件
4、直接拖到最后面看文件,这里变成aa了
同时研究一下为啥c++ why a class has two file .h and .cpp;
链接 :http://www.math.uaa.alaska.edu/~afkjm/csce211/handouts/SeparateCompilation.pdf
主要就这句:
By doing this, if your class implementation doesn’t change then it won’t need to be recompiled.
Most IDE’s will do this for you – they will only recompile the classes that have changed.
This is possible when they are split up this way, but it isn’t possible if everything is in one file (or if the implementation is all part of the header file).
并且一般头文件都有
#ifndef __KAIWPP_WPPINFOHELPER_SHAPEINFOHELPER_H__
#define __KAIWPP_WPPINFOHELPER_SHAPEINFOHELPER_H__
#endif //!__KAIWPP_WPPINFOHELPER_SHAPEINFOHELPER_H__
类似这个玩意,防止重定义,上面那个实验也可以验证这个
Compilation
The compilation step is performed on each output of the preprocessor. The compiler parses the pure C++ source code (now without any preprocessor directives) and converts it into assembly code. Then invokes underlying back-end(assembler in toolchain) that assembles that code into machine code producing actual binary file in some format(ELF, COFF, a.out, ...). This object file contains the compiled code (in binary form) of the symbols defined in the input. Symbols in object files are referred to by name.
Object files can refer to symbols that are not defined. This is the case when you use a declaration, and don't provide a definition for it. The compiler doesn't mind this, and will happily produce the object file as long as the source code is well-formed.
Compilers usually let you stop compilation at this point. This is very useful because with it you can compile each source code file separately. The advantage this provides is that you don't need to recompile everything if you only change a single file.
The produced object files can be put in special archives called static libraries, for easier reusing later on.
It's at this stage that "regular" compiler errors, like syntax errors or failed overload resolution errors, are reported.
Linking
The linker is what produces the final compilation output from the object files the compiler produced. This output can be either a shared (or dynamic) library (and while the name is similar, they haven't got much in common with static libraries mentioned earlier) or an executable.
It links all the object files by replacing the references to undefined symbols with the correct addresses. Each of these symbols can be defined in other object files or in libraries. If they are defined in libraries other than the standard library, you need to tell the linker about them.
At this stage the most common errors are missing definitions or duplicate definitions. The former means that either the definitions don't exist (i.e. they are not written), or that the object files or libraries where they reside were not given to the linker. The latter is obvious: the same symbol was defined in two different object files or libraries.
How does the compilation and linking process work?的更多相关文章
- Linking code for an enhanced application binary interface (ABI) with decode time instruction optimization
A code sequence made up multiple instructions and specifying an offset from a base address is identi ...
- Build Instructions (Windows) – The Chromium Projects
转自:http://121.199.54.6/wordpress/?p=1156 原始地址:http://www.chromium.org/developers/how-tos/build-instr ...
- AngularJs学习笔记--directive
原版地址:http://code.angularjs.org/1.0.2/docs/guide/directive Directive是教HTML玩一些新把戏的途径.在DOM编译期间,directiv ...
- JVMInternals--reference
This article explains the internal architecture of the Java Virtual Machine (JVM). The following dia ...
- Directive Definition Object
不知道为什么这个我并没有想翻译过来的欲望,或许我并没有都看熟透,不好误人子弟,原版奉上. Here's an example directive declared with a Directive D ...
- Python面试常见的问题
So if you are looking forward to a Python Interview, here are some most probable questions to be ask ...
- 什么是内联函数(inline function)
In C, we have used Macro function an optimized technique used by compiler to reduce the execution ti ...
- Debugging golang programs
https://ttboj.wordpress.com/2016/02/15/debugging-golang-programs/ I’ve been writing a lot of golang ...
- An Assembly Language
BUFFER OVERFLOW 3 An Assembly Language Introduction Basic of x86 Architecture Assembly Language Comp ...
随机推荐
- for循环比较
在实际的开发过程中,一般都会用到for循环,都可以用来遍历,但是这几个之间又存在细微的差别! 一,传统的for循环: var arr = ['good', 'good', 'study']; for ...
- Spock - Document -04- Interaction Based Testing
Interaction Based Testing Peter Niederwieser, The Spock Framework TeamVersion 1.1 Interaction-based ...
- hdu 4506 快速幂
小明自从告别了ACM/ICPC之后,就开始潜心研究数学问题了,一则可以为接下来的考研做准备,再者可以借此机会帮助一些同学,尤其是漂亮的师妹.这不,班里唯一的女生又拿一道数学题来请教小明,小明当然很高兴 ...
- javascript第一个作业之网页计算器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Eclipse上传新项目到GitLab
E&T: Eclipse; GitLab; GitLab和GitHub一样属于第三方基于Git开发的作品,免费且开源(https://github.com/gitlabhq/gitlabhq ...
- 谈一谈java中的Canves机制
0--写在前面: 很多初学java的童鞋,常常很苦恼,一天天的都跟命令行较劲,好像很无聊的样子,如果能跳出命令行做出界面甚至一个画图界面,那将是一件很兴奋的事情:也可以让编程变的有趣:有脑洞的同学还可 ...
- Ubuntu 16.04 LTS 安装 miniconda
Ubuntu 16.04 LTS 安装 miniconda 下载 miniocnda 的 bash 文件下载链接 https://conda.io/miniconda.html ,我选择的是 64-b ...
- 找出n之内的完全数, 并输出其因子
定义: 完全数:所有的真因子(即除了自身以外的约数)的和,恰好等于它本身.例如:第一个完全数是6,它有约数1.2.3.6,除去它本身6外,其余3个数相加,1+2+3=6.第二个完全数是28,它有约数1 ...
- OpenStack搭建Q版在控制节点上的环境准备(step2)
接下来是只需要在控制节点上准备的环境配置.其中虽然NTP服务需要在所有节点上都安装,但NTP服务在控制节点和其他的节点上的配置是不同的,所以不把它放在step1的公共配置中进行准备.如下: 1.配置N ...
- 专访笨叔叔:2019年可能是Linux年?(转)
链接:https://zhuanlan.zhihu.com/p/57815479 2017年9月<奔跑吧 Linux内核>一书出版后得到了广大Linux从业人员和爱好者(特别是从事Linu ...