C++程序编译之谜——简单还是复杂?编译到底有哪些步骤?

左手编程,右手年华。大家好,我是一点,关注我,带你走入编程的世界。

公众号:一点sir,关注领取编程资料

通常我们用IDE写完一个程序后,点击编译按钮的时候,内部到底发生了什么?为什么会生成一个可执行文件?这个过程到底有哪些步骤呢?是很简单还是很复杂呢?这篇文章,我们把这些事情讲清楚。

首先要明确一点,编译只是一个统称,编译的整个过程有预处理、编译、汇编和链接的过程

我们给出一个特别简单的程序

c 复制代码
//test.c
#include <stdio.h>
#define max 5
int main()
{
    printf("max = %d\n", max);
    return 0;
}

1、预处理

预处理阶段的指令一般都是以#来开头的,替换#include包含的头文件,替换#define定义的宏,删除注释,去掉#ifdef不符合条件的那一部分,所有#开头的代码都会在预处理阶段完成处理。

预处理命令:gcc -E test.c -o test.i

这里-E的作用是让程序在预处理完成之后就停止,为了方便我们后面的观察。我们在当前目录下ls,就可以看见多了一个test.i的文件,打开它可以看到很多变量、函数等等的声明,这些都是stdio.h这个头文件展开的结果,拉到最后,可以看到我们定义的宏max被替换成5了。

)

2、编译

大学如果学的是计算机专业的童鞋一定会学过一门《编译原理》的课,这门课几乎会把很多大学生折腾得死去活来。而这个编译的过程也正式编译原理里面介绍的内容,包括词法分析、语法分析、语义分析、程序优化等等一系列的过程,这些都是编译器的核心内容,如果你想开发编译器,这个过程你要非常非常的精通!这个过程就是把程序编译成更接近机器语言的汇编语言。平时我们用IDE编译的时候,经常看见的错误和警告,一般都是在过程发出的。

编译命令:gcc -S test.i -o test.s

这里-S的作用是让程序在编译完成之后就停止,为了方便我们后面的观察。我们在当前目录下ls,就可以看见多了一个test.s的文件,打开它看到的一大堆汇编指令。这些指令,我根本看不懂,说实话,没有接触过汇编语言的人,几乎都是看不懂的。但是如果你是想在编译器这个底层领域翻江倒海的话,汇编语言是必须要懂的。

3、汇编

汇编语言有些专业人员看得懂,但是计算机是根本就看不懂的。计算机看得懂的仅仅只有010101这种机器语言,所以我们还要将汇编语言转换成机器语言,至于这个过程怎么转的,不在本文的讨论范围,也讨论不了,因为我也不知道。这些都是那些非常厉害的大神的研究领域,真不是我夸大这个难度,能开发出商用编译器的人,至少在计算机领域绝对都是逆天的天选之子。

汇编命令:gcc -C test.i -o test.o

我们在当前目录下ls,就可以看见多了一个test.o的文件,打开它看到的一大堆乱码,实际上这些都是二进制命令,而这些命令才是计算机能看得懂的。

4、链接

二进制文件虽然计算机可以看懂了,但是如果你的源文件中用到了其他自己写的头文件的函数,或者是第三方静态库动态库,这时候还需要进行把它们链接起来生成可执行文件,才可以正确的被执行。

链接命令:gcc test.o -o test

但是如果引用的头文件是C/C++语言级别自带的话,换种说法就是,只有一个源文件,貌似不需要进行链接这一步,直接运行上面编译生成的.o文件也可以。反而进行链接操作的话会报这个错误,原因我暂时也没找到,如果知道的朋友欢迎留言评论。

/opt/rh/devtoolset-9/root/usr/libexec/gcc/x86_64-redhat-linux/9/ld: error in test.o(.eh_frame); no .eh_frame_hdr table will be created

以上就是编译的几个步骤,只有比较清晰地掌握好每个步骤,才能真正地把编译的整个流程搞清楚。当然,你也可以用一步到位的方式进行编译:

gcc test.c -o test

相关推荐
喵~来学编程啦6 小时前
【编译原理】编译原理知识点汇总·词法分析器(正则式到NFA、NFA到DFA、DFA最小化)
学习笔记·编译原理
喵~来学编程啦2 天前
【编译原理】编译原理知识点汇总·概论与文法
学习笔记·编译原理
Trouvaille ~3 个月前
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
c++·c++20·编译原理·编译器·类和对象·rvo·nrvo
无名之逆4 个月前
B树和B+树
javascript·数据结构·b树·算法·编译原理·期末速成
嚯呀怪怪怪4 个月前
从零基础学Go(九)——Go的Goroutine
golang·线程·多线程·并发·编译原理·协程·gorountine
Beginner x_u6 个月前
编译原理 第二章下: 推导,规约,句型句子,语言,文法分类,二义性
编译原理·语言·推导·文法
codists6 个月前
《编译原理》阅读笔记:p19-p24
编译原理
Beginner x_u6 个月前
编译原理 第一章: 编译概述 重点总结(翻译程序的过程,解释程序,编译程序的结构)
编译原理·解释程序·翻译程序·编译概述
Beginner x_u6 个月前
编译原理 第三章上 :词法分析 状态图的画法与检验
编译原理·词法分析·状态图
codists6 个月前
《编译原理》阅读笔记:p18
编译原理