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博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了