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

2022-07-11 13:36:59

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

一、常见文件后缀

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

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

       .cpp为后缀的文件:是c++源代码文件

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

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

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

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

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

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

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

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

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

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

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

// 新建hello.cpp文件,vim编辑

#include <iostream>

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”了,而这也就是链接的作用。

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

  • 作者:HUST_Miao
  • 原文链接:https://blog.csdn.net/u010183728/article/details/81630554
    更新时间:2022-07-11 13:36:59