大家知道计算机使用的一系列的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. Verilog_Day2_Plus

    内容为书中第4章 等式运算符 “==” 与 “===” 的区别 Verilog中存在4种等式运算符: == (等于); != (不等于); === (等于); !== (不等于). “==”与&quo ...

  2. JAVAWEB servlet和jsp的权限访问控制

    要想防止用户直接访问某个页面,那么就需要要求他带着session来访问,我们才让他访问,所以登录时设置的session就用上了 在用户没有session时,访问servlet或者jsp时直接重定向页面 ...

  3. [TJOI2013]拯救小矮人[排序+dp]

    题意 题目链接 分析 Imagine的完美回答 重点大概是证明我们选出要救的小矮人一定可以根据 \(a_i+b_i\) 的大小进行排序救出. 注意这里关注的对象是可以保留的高度,所以我们的dp值才会表 ...

  4. Docker系列之CentOS7安装Docker(一)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 一.瞎扯淡(只讲有用的) 感兴趣的同学可以上网搜索一下docker具体的介绍.我这边主要介绍偏实战的内容,不喜勿喷,有问题也请指出 ...

  5. Docker与CI持续集成/CD(转)

    背景 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会 ...

  6. 10min 手写一个内存监控系统

    本文的目的在于,尽可能用简单的代码,让大家了解内存监控的原理,及思想.更容易去理解Nagios.Zabbix.Ganglia监控原理,文章最后还有视频教程链接哦,从零敲出来的全过程 思路分为下面几块: ...

  7. Cloud Native Weekly | 华为云抢先发布Redis5.0,红帽宣布收购混合云提供商 NooBaa

    1——华为云抢先发布Redis5.0 2——DigitalOcean K8s服务正式上线 3——红帽宣布收购混合云提供商 NooBaa 4——微软发布多项 Azure Kubernetes 服务更新 ...

  8. 180801-Spring之定时任务基本使用篇

    文章链接:https://liuyueyi.github.io/hexblog/2018/08/01/180801-Spring之定时任务基本使用篇/ Spring之定时任务基本使用篇 spring- ...

  9. 微软Word制作自己的模板

    我们在用Word的时候,很多时候需要一定的格式. 这个时候,*.dotx文件出场了!它将带给我们自己的模板. 步骤: 首先,新建一个文档,选择空白文档: 图片大就大吧,不要在意这些细节. 编辑一下,保 ...

  10. 腾讯云linux+kodexplorer可道云搭建私有云盘

    kodexplorer可道云介绍KodExplorer可道云,原名芒果云,是基于Web技术的私有云和在线文件管理系统.致力于为用户提供安全可控.可靠易用.高扩展性的私有云解决方案.用户只需通过简单环境 ...