欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++ —— C++程序编译的四个过程

程序员文章站 2022-04-23 17:21:05
g++是Linux下C++的编译器;我为什么会选择Linux下的g++编译器,就是因为g++可以看到程序从编译到运行的过程做了些什么。而VS等集成开发环境看不到这些,并不是说VS工...

g++是Linux下C++的编译器;我为什么会选择Linux下的g++编译器,就是因为g++可以看到程序从编译到运行的过程做了些什么。而VS等集成开发环境看不到这些,并不是说VS工具不好,(VS还是相当好用的...)。对于学习来说,需要知道程序从编译到运行进行了哪些工作,做了哪些事情,首推g++编译器(这个看个人习惯)。

一、常见文件后缀

.c为后缀的文件:c语言源代码文件

.a为后缀的文件:是由目标文件构成的库文件

.C,.cc为后缀的文件:是c++源代码文件

.h为后缀的文件:头文件

o为后缀的文件:是编译后的目标文件

.s为后缀的文件:是汇编语言源代码文件

.m为后缀的文件:Objective-C原始程序

.so为后缀的文件:编译后的动态库文件

 

二、g++执行的四个过程

1、预处理:条件编译,头文件包含,宏替换的处理,生成.i文件。

2、编译:将预处理后的文件转换成汇编语言,生成.s文件

3、汇编:汇编变为目标代码(机器代码)生成.o的文件

4、链接:连接目标代码,生成可执行程序

 

三、最简单的C++程序——"helloworld!\n"

 

// 新建hello.cpp文件,vim编辑
#include 
using namespace std;
 
int main(void)
{
    count << "hello world!"<< endl;
 
    reutrn 0;
}

 

(1)预处理阶段

 

g++ -E hello.cpp > hello.i

 

通过vim打开hello.i文件,你会发现一些情况(最好是自己观察,看看哪些内容被换了);

宏的替换,还有注释的消除,还有找到相关的库文件,将#include文件的全部内容插入。若用<>括起文件则在系统的INCLUDE目录中寻找文件,若用""括起文件则在当前目录中寻找文件。

用编辑器打开hello.i会发现有很多很多代码,你只需要看最后部分就会发现,预处理做了宏的替换,还有注释的消除,可以理解为无关代码的清除。

(2)编译

 

g++ -S hello.cpp

 

生成hello.s文件,.s文件表示是汇编文件,用编辑器打开就都是汇编指令。(可以通过vim编辑器看看hello.s里面的内容【都是汇编指令,哈哈】)。

(3)汇编

 

g++ -c hello.cpp

 

汇编变为目标代码(机器代码)生成.o的文件,.o是gcc生成的目标文件,用编辑器打开就都是二进制机器码。

(4)链接 ——链接生成可执行文件(库文件进行链接)

 

g++ -o hello hello.cpp

 

程序运行:./hello【输出hello world!】

 

在成功编译之后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库(可以这么理解就是不带main()函数的.cpp生成的)。

可以重新查看这个小程序,在这个程序中并没有定义”cout”的函数(准确说cout不是函数,cout却很独特:既不是函数,似乎也不是C++特别规定出来的像if,for一类有特殊语法的“语句”,其实说到底还是函数调用,不过这函数有些特殊,用的是运算符重载,确切地说是重载了“<<”运算符。这里如果用pritf()函数说明会更好,暂且当做函数理解吧)实现,且在预编译中包含进的”iostream”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现”cout”函数的呢?系统把这些函数实现都被做到名为stdc++的库文件中去了,在没有特别指定时,g++会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到stdc++库函数中去,这样就能实现函数”cout”了,而这也就是链接的作用。