C++编译与链接(1)-编译与链接过程

大家知道计算机使用的一系列的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=100;
~

*在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

最终运行结果如下

#include <iostream>
int i=100;

~

参考文献

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

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

C++编译与链接(1)-编译与链接过程,布布扣,bubuko.com

时间: 2024-10-14 00:48:59

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

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

在Linux下编译Lua时,我一般都是使用的make generic,这样编译没有什么问题,运行lua的程序也都OK,但是,这样在加载外部的C动态 链接库,却总是报下面的错误 dynamic libraries not enabled; check your Lua installation 查找了半天资料,最后发现,如果是以make generic对Lua进行编译,是没法进行动态链接的. 所以可以选择以其他的平台参数,选择make linux进行编译的话,就可以加载外部的动态链接库, 但是在使

简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

一个程序简单的程序如下: 1 hello.h #ifndef HELLO_H#define HELLO_H void hello(const char *name); #endif 2 hello.c #include <stdio.h>#include <stdlib.h> void hello(const char *name){ printf("hello %s\n",name);} 3 main.c #include <stdio.h>#in

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

一. C程序编译过程 编译过程简单介绍 : C语言的源文件 编译成 可运行文件须要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (assembly) 得到机器码, 连接 (linking) 得到可运行文件; -- 查看每一个步骤的编译细节 : "-E" 相应 预处理, "-S" 相应 编译, "-c" 相应 汇编, "-O" 相应 连接; -- 每一个步骤

gcc 学习笔记(一) - 编译C程序 及 编译过程

一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (assembly) 得到机器码, 连接 (linking) 得到可执行文件; -- 查看每个步骤的编译细节 : "-E" 对应 预处理, "-S" 对应 编译, "-c" 对应 汇编, "-O" 对应 连接; -- 每个步骤对应的工

vc判断是32位编译还是64位编译判断是debug编译还是release编译

来源:http://www.greensoftcode.net/   发布日期:2014-03-28      点击次数:471 发布者IP:119.119.236.22 1.判断是debug编译还是release编译.如果_DEBUG定义了表示是debug编译,否则是release编译. 2.判断是32位编译还是64位编译.在 Win32 配置下,_WIN32 有定义,_WIN64 没有定义.在 x64 配置下,两者都有定义.即在 VC 下,_WIN32 一定有定义.因此,WIN32/_WIN

jvm内存模型,java类从编译到加载到执行的过程,jvm内存分配过程

一.jvm内存模型 JVM 内存模型主要分为堆.程序计数器.方法区.虚拟机栈和本地方法栈 1.堆 1.1.堆是 JVM 内存中最大的一块内存空间. 1.2.该内存被所有线程共享,几乎所有对象和数组都被分配到了堆内存中. 1.3.堆被划分为新生代和老年代,新生代又被进一步划分为 Eden 和 Survivor 区,最后 Survivor 由 From Survivor 和 To Survivor 组成. 2.程序计数器(Program Counter Register) 程序计数器是一块很小的内存

一段程序从编译到硬件再到执行的过程

(以下内容还未整理好,谨慎观看哈哈哈) 前言知识: 主存储器:是整个存储系统的核心,它用来存放计算机运行期间所需要的程序和数据,CPU可直接随机地对它进行访问. (主存地读写操作是在控制器地控制下进行的,只有接收到来自控制器地读写命令或写允许后,才能实现正确地读写操作) CPU:是整个计算机地核心,是对指令流和数据流在时间上与空间上实施正确地控制. (指令流:指的是CPU执行的指令序列:数据流:指的是根据指令操作要求依次存取数据地序列) 若用计算机来解决某个问题,首先要为这个问题编制解题程序,而

linux-裁剪Linux功能,编译/bin/login, busybox编译linux

linux功能:终端提示信息 [[email protected] ~]# cat /etc/issueRed Hat Enterprise Linux Server release 5.8 (Tikanga)Kernel \r on an \m [[email protected] ~]# uname -r2.6.18-308.el5[[email protected] ~]# uname -mx86_64[[email protected] ~]# linux功能:用户 nsswitch:

制作由下向上的滚动字幕,字幕内容要求包含网站超级链接和图片超级链接, 使用鼠标移动事件控制字幕运动和停止。 2、在下拉列表框中设置五种以上颜色,选择颜色后, 滚动字幕背景色改变成相应颜色

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>    </head>    <!--        时间:2016-12-28        描述:1.制作由下向上的滚动字幕,字幕内容要求包含网站超级链接和图片超级链接,                   使用鼠标移动事件控制

预编译文件,预编译头文件认识

一.概念:1.预编译:就是编译器首先编译某个文件(称为预编译头文件),然后将这个编译结果保存起来,之后如果有其他源文件include了这个“预编译头文件”的时候,则自动从这个编译结果提取需要的信息进行编译.2.预编译结果文件(Precompiled header file):就是那个用来保存已经编译了的符号信息的文件(.PCH作为后缀)3.生成预编译结果文件(Create Precompiled header file):我们说源文件A通过文件B“生成预编译结果文件”是指编译A的时候将其中编译B