C++代码编译过程
Published on 2024-09-19 22:02 in Loading... with 红彡sakura

C++代码编译过程

代码转换成可执行文件的全过程

看了一些网上的文章,觉的还是自己写写看看才能理解通透,也为找简历做准备。

代码转换成可执行文件分为4个步骤,预处理、编译、汇编、链接。

预处理

这个过程是执行代码中的一些预处理指令,多说无益,直接上代码

#include <iostream>
#define Best true;
#ifdef DEBUG
using namespace std;
#endif // DEBUG
int main()
{
Best;
printf("Hello World!\r\n");
return 0;
}

这是一个C++源码,等它预处理完成后会怎么样?

vs2019可以在项目属性-预处理器-预处理到文件夹-是,在项目的Debug文件夹中会有生成的.i文件。

#line 1 "D:\\CppRes\\Yidaoyun\\C++学习疑难\\VirtualFunction.cpp"
#pragma external_header(push)
#line 1 "D:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\include\\iostream"
#pragma once
#pragma external_header(push)
#line 1 "D:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\include\\yvals_core.h"
#pragma once
...

为什么用省略号,因为生成后的.i文件实在太长了,足足有64211行,拿出去也可以吹写了6w+行代码了hh(其实一半都是空行)。

可能有人会好奇,为什么预处理完成之后还有#pragma之类的预处理命令,我在该文件中find了一下,发现#include、#define、#ifdef之类的命令都不存在,所以可以得出,这三种命令应当是执行完了。

#include命令是将其他文件中的源码复制过来,这点应该很好理解;#define命令是将宏替换成定义,在我的代码中就体现为把所有Best替换为true;#ifdef则是判断条件,如果条件符合就将中间的代码加入到.i文件中,避免编译不需要的代码造成可执行文件冗余。

那么其他带#的命令是干嘛的呢?就不赘述了,唯一有一点比较好奇的是为什么预处理完成之后还有#pragma命令?

我有一种推测,.i文件里#line命令用于控制预定义宏,而#pragma跟代码一样作为指令控制系统和主机,两者都作为CPU的执行代码存在于.i文件中,不可被省略。

编译

这时需要对.i文件进行词法分析、语法分析、语义分析,我好像记得在搜索引擎里学过类似的概念这个讲起来比较复杂,回头留个专栏讲这个。

//TODO:编译原理

汇编

将源码转换为机器码,不过编译器会对机器码进行优化,生成.o文件即二进制可重定向文件。

链接

链接过程可分为静态链接和动态链接。静态链接即将不同.o文件的相似字段进行合并,生成可执行文件。动态链接即程序启动才将dll文件加入到exe文件中执行。

//TODO:研究静态链接和动态链接

参考文献

C/C++:编译全过程——预处理、编译、汇编、链接(包含预处理指令:宏定义,文件包括、条件编译)_怎么在devc++里面把c文件变成汇编语言-CSDN博客

C/C++ 预处理器参考 | Microsoft Learn

程序的静态链接,动态链接和装载 - Szz - 博客园 (cnblogs.com)

posted @   Isakura红  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示