大家知道计算机使用的一系列的1和0

那个一个C++语言程序又是如何从一个个.h和.cpp文件变成包含1和0的可执行文件呢?

可以认为有以下的几个环节

源程序->预处理->编译和优化->生成目标文件->链接->可执行文件

1.预处理

C++的预处理是指在C++程序源代码被编译之前,由预处理器对C++程序源代码进行的处理。这个过程并不对程序的源代码进行解析。

这里的预处理器(preprocessor)是指真正的编译开始之前由编译器调用的一个独立程序。

预处理器主要负责以下的几处

1.宏的替换

2.删除注释

3.处理预处理指令,如#include,#ifdef

如我们有以下代码

temp.h

#ifndef   _HEADERNAME_H
#define _HEADERNAME_H 1 #include <iostream>
inline void show(char *a)
{
std::cout << a<< std::endl;//annotation
} #endif

main.cpp

#include "temp.h"
#define MACRO "This is a macro" extern int i;
int main()
{
std::cout<<i<<std::endl;
show(MACRO);
}

a.cpp

#include <iostream>
int i=;

*在vs2013中可以使用“VS2013 开发人员命令提示”

使用cl /P main.cpp只进行预编译生成main.i文件

*g++中可以使用(在以下只使用g++进行演示)

g++ –E main.cpp>main.i命令

g++ –E a.cpp>main.i

打开生成的A.i文件

我们发现

1、show函数中的注释已经被删掉了

2、main函数中的MACRO宏被替成了"this is a macro”

windows vs下

3、temp.h和main.cpp中的#include<iostream> 和#include “temp.h”也在相应位置被展开了

2.编译和优化

词法分析 -- 识别单词,确认词类;比如int i;知道int是一个类型,i是一个关键字以及判断i的名字是否合法

语法分析 -- 识别短语和句型的语法属性;

语义分析 -- 确认单词、短语和句型的语义特征;

代码优化 -- 修辞、文本编辑;

代码生成 -- 生成译文。

内联函数的替换就发生在这一阶段

在g++中可以使用

g++  -S将预处理阶段生成的.i文件生成相应的汇编文件

g++ –S main.i main.s

g++ –S a.i a.s

生成的部分代码如下:

3.生成目标文件

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。

在最终的目标文件中

除了拥有自己的数据和二进制代码之外,还要至少提供2个表:未解决符号表和导出符号表,分别告诉链接器自己需要什么和能够提供什么。

编译器把一个cpp编译为目标文件的时候,除了要在目标文件里写入cpp里包含的数据和代码,还要至少提供3个表:未解决符号表,导出符号表和地址重定向表。

未解决符号表提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。

导出符号表提供了本编译单元具有定义,并且愿意提供给其他编译单元使用的符号及其地址。

地址重定向表提供了本编译单元所有对自身地址的引用的记录。

g++中可以使用g++ -c命令

g++ –c main.s –o main.o

g++ –c a.s –o a.o

4.链接

由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。

g++ a.o main.o –o main.out

最终运行结果如下

100

This is a macro

参考文献

C/C++程序从编译到最终生成可执行文件的过程分析 http://blog.csdn.net/wyb19890515/article/details/7211006

c/c++程序编译连接过程 http://blog.csdn.net/hitprince/article/details/7880241

C++编译与链接(1)-编译与链接过程的更多相关文章

  1. C/C++程序编译流程(预处理->编译->汇编->链接)

    程序的基本流程如图: 1. 预处理 预处理相当于根据预处理指令组装新的C/C++程序.经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内 ...

  2. GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】

    4.1.2 符号解析与重定位 (1)重定位 在完成空间和地址的分配步骤之后,链接器就进入了符号解析和重定位的步骤,这是静态链接的核心部分. 先看看 a.o 的反汇编文件: objdump -d a.o ...

  3. 使用MinGW编译Boost,MSVC编译Boost的几种链接方式 good

    1.下载Boost(http://www.boost.org) 我目前用的是1.61.0版本 2.将MinGW下的bin目录完整路径设置到系统环境变量Path中,保证cmd命令行能找到gcc,g++等 ...

  4. GO 使用静态链接库编译 生成可执行文件 使用第三方 .a 文件,无源码构造

    go build 和 go install 都需要使用源码来进行编译.但是有时候我们只有.a或者.so文件.并不能获取到第三方库的源码,这时我们需要静态链接库编译的技巧: 上图是实验前的文件分布. 使 ...

  5. linux下C/C++编译时系统搜索 include 和 链接库 文件路径的指定

     C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径.   ...

  6. C++ 多文件编译简述:头文件、链接性、声明与定义

    目录 Commen Sense 头文件 链接性 static 与链接性控制 extern 与外部链接性 Reference Commen Sense C++ 在编译时对每个翻译单元(Translati ...

  7. CentOS下编译Lua使得其支持动态链接

    在Linux下编译Lua时,我一般都是使用的make generic,这样编译没有什么问题,运行lua的程序也都OK,但是,这样在加载外部的C动态 链接库,却总是报下面的错误 dynamic libr ...

  8. 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

    一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...

  9. [转]静态库、动态库,dll文件、lib文件,隐式链接、显式链接

    转自:https://blog.csdn.net/dcrmg/article/details/53427181 静态链接.动态链接 静态库和动态库分别应用在静态链接方式和动态链接方式中,所谓静态链接方 ...

  10. nginx 编译安装时的编译参数说明(不建议看)

    https://www.cnblogs.com/wazy/p/8108824.html ./configure --user=www \ #worker进程运行用户 --group=www \ #wo ...

随机推荐

  1. CBrother异或加密与C++异或加密函数

    CBrother脚本异或加密与C++异或加密函数 异或对于数据加密来说是最简单的方式,在一般的安全性要求不是非常高的地方,异或加密是最好的选择. C++异或加密代码 int g_PWD = 0xffe ...

  2. 生死系列--SongXingZhi

    SongXingZhi,我上中专时的同学,任劳动委员,湖北随州人.其实在上学以及毕业后,我们俩没什么交往,也没说过几句话. 印象比较深的一次是在上什么课时,老师拖堂了 ,他直接从课桌上翻过来,从后门出 ...

  3. 洛谷 P1350 车的放置

    洛谷 P1350 车的放置 题目描述 有下面这样的一个网格棋盘,a,b,c,d表示了对应边长度,也就是对应格子数. 当a=b=c=d=2时,对应下面这样一个棋盘 要在这个棋盘上放K个相互不攻击的车,也 ...

  4. Kubernetes学习之路(十七)之statefulset控制器

    目录 一.statefulset简介 二.为什么要有headless?? 三.为什么要 有volumeClainTemplate?? 四.statefulSet使用演示 (1)查看statefulse ...

  5. iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字

    iOS开发-通过正则表达式判断字符串是否为纯阿拉伯数字 简述:NSString * regex_0 = @"\\d{1,}";   /*允许首位为0*/ NSString * re ...

  6. JAVA Eclipse 快捷键 ctrl+f 查找/替换 字符串

  7. Java类的加载的一个小问题

    前言 之前写了一篇文章专门介绍了一下类的加载和对象的创建流程,然后收到了一个博友的疑问,觉得蛮好的,在这里和大家分享下. 博文地址:[Java基础]Java类的加载和对象创建流程的分析 疑问 类在加载 ...

  8. Python之闭包函数、装饰器

    1.闭包函数 #作用域关系在函数定义阶段时就已经固定死了,与调用位置无关 # 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系 # def f1(): # x=1 # def inner(): ...

  9. Spring是什么?优点是什么?

    大部分项目都少不了Spring的身影,为什么大家对他如此青睐,而且对他的追捧丝毫没有减退之势呢 Spring是什么: Spring是一个轻量级的DI和AOP容器框架. 说它轻量级有一大部分原因是相对与 ...

  10. UnityEditor扩展-右键拷贝资源路径到系统剪贴板

    要点速记 命令添加到右键菜单 [MenuItem("Assets/Copy Asset Path")] 或 [MenuItem("Assets/Copy Asset Pa ...