当前位置: 首页 > news >正文

C++ 编译过程(附简单实例)

C++ 采用分离编译模式,分离编译指的是,一个程序/项目是由若干个源文件共同实现,编译时先把每个源文件单独编译生成目标文件,再将所有目标文件连接起来,形成单一的可执行文件。
C++ 编译的四个阶段:预处理、编译、汇编和链接
这里以 g++ 为例,用到的文件分别为 mymath.hmymath.cppmain.cpp ,代码如下:

// mymath.h
extern int add(int, int);
// mymath.cpp
#include "mymath.h"
// implement func 'add'
int add(int n1, int n2) {return (n1 + n2);
}
// main.cpp
#include <iostream>
#include "mymath.h"
#define ADD1 5
#define ADD2 6int main() {// call func 'add' defined in <mymath.h> file// and printstd::cout << add(ADD1, ADD2) << std::endl;return 0;
}

c++编译过程

1. 预处理(Preprocessing)
1)读取C/C++源程序,对其中的伪指令(以#开头的指令)进行处理,包括:
a. 将所有的“#define”删除,并且展开所有的宏定义。
b. 处理所有的条件编译指令,如:“#if”、“#ifdef”、“#elif”、“#else”、“endif”等。这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉。
c. 处理 “#include” 预编译指令,将被包含的文件插入到该预编译指令的位置。注意这个过程可能是递归进行的,也就是说被包含的文件可能还包含其他文件。
2)删除所有的注释。
3)添加行号和文件名标识。以便于编译时编译器产生调试用的行号信息及用于编译时产生的编译错误或警告时能够显示行号。
4)保留所有的#pragma编译器指令。

预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同源文件无异,只是内容上有所不同。

【补充】常用的预处理指令包括:
宏定义:#define
文件包含:#include
条件编译:#if、#elif、#ifndef、#ifdef、#endif、#undef
错误信息指令:#error
#line指令
布局控制:#pragma
【注意】预处理不做语法检查。

g++ 为例,g++ 使用参数 -E 对源文件进行预处理,并在预处理后退出而不会进行后续的编译操作:

g++ -E mymath.cpp -o mymath.i
g++ -E main.cpp -o main.i 

如果头文件和cpp 文件不在同一目录下,可以通过参数 I 来指定。

g++ -E -Iheader_dir src.cpp -o target.i

经过预处理后的文件大小会有一定的增加:

$ wc -l main.cpp main.i13 main.cpp55993 main.i56006 total
$ wc -l mymath.cpp mymath.i7 mymath.cpp17 mymath.i24 total

2.编译(Compilation)
将源文件转换成特定汇编代码(assembly code),在这一阶段会执行语法检查。

g++ 为例,使用参数 -S 对预编译后的文件编译生成汇编代码。

g++ -S mymath.i -o mymath.s
g++ -S main.i -o main.s   

【注意】
a. 这里的源文件,它既可以是源代码文件,也可以是源代码预处理之后的文件,如果输入文件是源代码文件,那么该命令会同时执行预处理和编译。如果是已经预处理后的文件,那么直接执行编译。
b. 预处理和编译生成的文件都是文本文件,可以直接在文本编辑器中打开并查看。

3.汇编(Assemble)
将汇编代码转换成机器码(machine code),生成可重定位目标程序的目标文件,目标文件是二进制格式,字节编码是机器指令。
【补充】汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译即可。

g++ 为例,使用参数 -c 对编译后的文件编译生成汇编代码。

g++ -c mymath.s -o mymath.o
g++ -c main.s -o main.o

4.链接(Linking)
链接过程将多个目标文以及所需的库文件链接成最终的可执行文件(executable file)。
由汇编程序生成的目标文件并不能被立即执行,其中可能还有许多没有解决的问题。例如某个源文件中的函数可能引用了另一个源文件中定义的某个符号(变量或者函数调用等);在程序中可能调用了某个库文件中的函数,诸如此类。这些问题都需要经过链接程序的处理来解决。
例如在上面的例子中,main.cpp 用到的 add 函数,就是在另一个文件 mymain.cpp 中定义的。
链接程序的主要工作就是将有关的目标文件彼此相连接,即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。

g++ 为例:

g++ main.o mymath.o -o main.out

有时候需要用到第三方库,这个时候可以使用参数 -l

g++ tmp.o -Ithirdpart_header_dir -Lthirdpart_dir -lthirdpart_lib_name 

【最后的补充】按步编译不是必须的,大多数时候 C++ 的编译是这样的:

g++ main.cpp mymath.cpp -o main.out

:)


【关于各阶段生成的文件后缀名】
1.预处理,生成.i的文件;
2.编译,生成 .s 文件.s;
3.汇编,生成.o的文件;
4.链接,生成可执行程序 .o。

最开始我以为输出文件的命名其实是在参数 -o 后自定义的,尝试修改后缀为 “.p1” 或者其他自定义后缀后,发现继续执行下一阶段的时候会提示:

'linker' input unused [-Wunused-command-line-argument]

也就是说,编译器 g++ 会检查命令行中指定的输入文件的后缀名,以此来识别文件类型,暂时没有找到相关资料,后续补充。

相关文章:

C++ 编译过程(附简单实例)

C 采用分离编译模式&#xff0c;分离编译指的是&#xff0c;一个程序/项目是由若干个源文件共同实现&#xff0c;编译时先把每个源文件单独编译生成目标文件&#xff0c;再将所有目标文件连接起来&#xff0c;形成单一的可执行文件。 C 编译的四个阶段&#xff1a;预处理、编译…...

ThingsBoard教程(五四):规则节点解析 Azure IoT Hub Node, RabbitMQ Node

Azure IoT Hub Node Since TB Version 2.5.3 配置 主题 - 获取有关IoT Hub主题的更多信息,请使用以下链接。主机名 - Azure IoT Hub主机名。设备ID - 来自Azure IoT Hub的设备ID。凭据 - Azure IoT Hub连接凭据。可以是共享访问签名或PEM格式证书。Azure IoT Hub支持不同的…...

元素偏移量offset

文章目录 1. offset概述2. offset与style的区别 1. offset概述 offset就是偏移量&#xff0c;我们使用offset系列相关属性可以动态的得到该属性的位置&#xff08;偏移&#xff09;、大小等。 element.offsetParent 返回作为该元素带有定位的父级元素&#xff0c;如果父级都没…...

如何让自动化测试框架更自动化?

一、引言 ​对于大厂的同学来说&#xff0c;接口自动化是个老生常谈的话题了&#xff0c;毕竟每年的MTSC大会议题都已经能佐证了&#xff0c;不是大数据测试&#xff0c;就是AI测试等等&#xff08;越来越高大上了&#xff09;。不可否认这些专项的方向是质量智能化发展的方向&…...

无屏幕实现连接树莓派

无屏幕实现连接树莓派 欢迎来到我的博客&#xff01;今天我将与大家分享如何无需使用屏幕&#xff0c;实现与树莓派的连接。对于那些在树莓派项目中不方便使用屏幕的人来说&#xff0c;这将是一个有用的技巧。 材料清单 在开始之前&#xff0c;让我们先准备好所需的材料&…...

【Android】AMS(一)系统启动流程

前言 AMS&#xff08;Activity Manager Service&#xff09;即活动管理器服务&#xff0c;是Android系统中的一个核心服务。它主要负责管理应用程序的生命周期&#xff0c;包括启动应用程序、切换应用程序、管理任务栈等。 Android启动流程 Android程序的启动流程可以概括为…...

FineBI6.0基础学习第一课 数据门户

PC端门户使用示例 首先,以管理员身份登录FineBI系统,安装数据门户,安装步骤见官网 新建一个数据门户...

如何部署项目到Tomcat + 第一个Servlet程序

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 目录 文章目录 一、Tomcat 1.1 Tomcat是什么 1.2 下载安装 1.3 部署项目 二、第一个Servlet程序 2.1 Servlet是什么 2.2 创建Maven项目 2.3 引入依赖 2.4 创建目录 2.5 编写类方法 2.6 打包…...

牛客刷题(HTML-Day1)

第一题&#xff1a; 1.下列代码在页面中显示的内容为&#xff08; &#xff09; <!DOCTYPE html> <html> <body> <p>hello<q>html</q></p> </body> </html> A hello“html” B hello html C hello“”html D 其他几…...

性能测试如何入门?熬夜7天整理出这一份3000字超全学习指南

赶鸭子上架要我搞性能测试&#xff0c;怎么办&#xff1f; 我第一次真正意义上搞性能测试是在2014年。项目组要求搞性能测试&#xff0c;我之前也没搞过&#xff0c;对服务端也不熟悉。就那么一脸懵逼地开始搞性能。当时我连linux上有哪些能看系统资源的命令都不知道。稀里糊涂…...

信息安全实践1.2(重放攻击)

前言 这个实验是看一本书做的&#xff0c;就是李华峰老师的书——《Metasploit Web 渗透测试实战》&#xff0c;我之前写过一篇Slowloris DoS攻击的博客&#xff0c;也是看这本书写的&#xff0c;总的来说&#xff0c;有用处。这篇博客其实也只是很浅显的去做一下重放攻击。 要…...

上海亚商投顾:沪指高开高走 地产股迎来久违反弹

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 三大指数今日高开高走&#xff0c;沪指午后涨近1%&#xff0c;深成指、创业板指涨超1.2%&#xff0c;上证50盘中大…...

Vim学习笔记【Ch02】

Vim学习笔记 系列笔记链接Ch02 Buffers, Windows, TabsBuffers什么是buffer查看所有bufferbuffer之间的切换删除buffer退出所有窗口 Windows窗口的创建窗口切换快捷键其他快捷键 Tabs什么是tabtab相关命令 window和buffer结合的3D移动小结 系列笔记链接 Ch00&#xff0c;Ch01 …...

《低代码指南》——低代码维格云能源行业解决方案

目录 典型场景介绍: 一、能源资产管理 二、碳核查 三、配电运营 总 结: 从业界实际情况来看,流程建设本身是一个对业务现实进行抽象的过程,这个过程即使不考虑软件开发的门槛,对于很多客户而言也是个涉及较长周期的复杂工作,往往需要咨询专家或专业公司帮助其建设内…...

【自制C++深度学习推理框架】Layer的设计思路

Layer的设计思路 Layer的抽象 如果将深度学习中的所有层分为两类, 那么肯定是"带权重"的层和"不带权重"的层。 基于层的共性&#xff0c;我们定义了一个Layer的基类&#xff0c;提供了一些基本接口&#xff0c;并可以通过继承和多态机制实现不同类型的L…...

Rust每日一练(Leetday0011) 下一排列、有效括号、搜索旋转数组

目录 31. 下一个排列 Next Permutation &#x1f31f;&#x1f31f; 32. 最长有效括号 Longest Valid Parentheses &#x1f31f;&#x1f31f;&#x1f31f; 33. 搜索旋转排序数组 Search-in-rotated-sorted-array &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷…...

STL --- 五. 函数对象 Function Objects

目录 1、函数对象的定义和作用 2、函数对象的分类和使用 3、std 常用的函数对象 4、函数对象的适配器 5、std 算法和函数对象区别 1、函数对象的定义和作用 STL&#xff08;Standard Template Library&#xff09;中的函数对象&#xff08;Functor&#xff09;是一种重载…...

Java IO 流操作详解

Java IO 流操作详解 一、简介1. 什么是IO流2. IO流的分类3. IO流的作用 二、Java IO流的输入操作1. 文件输入流2. 字节输入流3. 缓冲输入流4. 对象输入流 三、Java IO流的输出操作1. 文件输出流2. 字节输出流3. 缓冲输出流4. 对象输出流 四、Java IO流的常用方法解析1. 字节读写…...

Halcon 形状匹配参数详解

find_shape_model(Image : : ModelID, AngleStart, AngleExtent, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness : Row, Column, Angle, Score) find_shape_model(Image : : //搜索图像 ModelID, //模板句柄 AngleStart, // 搜索时的起始角度 AngleExte…...

C++11强类型枚举

C11引入了强类型枚举&#xff08;enum class&#xff09;&#xff0c;也称为枚举类。 强类型枚举是一种更加类型安全的枚举类型&#xff0c;相对于传统的枚举类型&#xff0c;强类型枚举可以提供更好的安全性和可读性。 强类型枚举的格式如下&#xff1a; enum class 枚举名 …...

终极指南:如何深度探索Alerter的10个隐藏高级功能

终极指南&#xff1a;如何深度探索Alerter的10个隐藏高级功能 【免费下载链接】Alerter Tapadoo/Alerter: 是一个简单易用的 Android 通知和进度条控件库。适合对 Android 开发、用户界面以及想要在 Android 应用中显示通知和进度条的开发者。 项目地址: https://gitcode.com…...

4步完整指南:如何用OpenCore Legacy Patcher让旧Mac重获新生

4步完整指南&#xff1a;如何用OpenCore Legacy Patcher让旧Mac重获新生 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 想让被苹果抛弃的旧Mac电脑重新运行最…...

Transformer位置编码避坑指南:手把手教你用RoPE解决长文本外推难题(附Torch复现)

Transformer长文本处理实战&#xff1a;RoPE位置编码的工程化解决方案 在构建现代NLP系统时&#xff0c;处理长文本序列一直是Transformer架构面临的重大挑战。当序列长度超过模型预训练时的最大位置编码范围时&#xff0c;传统方法的性能会显著下降。这种现象在构建聊天机器人…...

TradingAgents-CN智能交易系统:3种部署方案让你5分钟开启AI投资分析

TradingAgents-CN智能交易系统&#xff1a;3种部署方案让你5分钟开启AI投资分析 【免费下载链接】TradingAgents-CN 基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版 项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN 还在为复杂的金融…...

Wan2.2-I2V-A14B实战案例:地方政府生成‘乡村振兴’政策解读动画短视频系列

Wan2.2-I2V-A14B实战案例&#xff1a;地方政府生成乡村振兴政策解读动画短视频系列 1. 项目背景与需求分析 近年来&#xff0c;随着数字政务的快速发展&#xff0c;各级地方政府越来越重视利用新媒体技术进行政策宣传。某地方政府计划开展"乡村振兴"系列政策解读工…...

Python: 多优化算法TSP求解方案,物流路径规划代码实践 - 附详尽注释及标准数据集

Python&#xff1a;模拟退火算法、蚁群算法、遗传算法、粒子群算法求解旅行商问题(TSP)的Python代码程序。 物流路径规划问题。 -- 数据集采用的tsplib标准数据集&#xff0c;可以根据自己需求修改城市坐标。 代码完整&#xff0c;注释详细&#xff0c;打印每次迭代结果&#x…...

Guohua Diffusion 创意编程:用Processing可视化交互控制图像生成

Guohua Diffusion 创意编程&#xff1a;用Processing可视化交互控制图像生成 你有没有想过&#xff0c;自己随手画的一条线、选择的一个颜色&#xff0c;能立刻变成一幅由AI生成的完整画作&#xff1f;这听起来像是科幻电影里的场景&#xff0c;但现在&#xff0c;通过一点创意…...

Phi-4-mini-reasoning企业应用探索:智能客服知识推理模块集成方案

Phi-4-mini-reasoning企业应用探索&#xff1a;智能客服知识推理模块集成方案 1. 轻量级推理模型的价值 在当今企业智能化转型浪潮中&#xff0c;轻量级推理模型正成为技术落地的关键。Phi-4-mini-reasoning作为一款专注于高质量推理的开源模型&#xff0c;凭借其128K令牌的超…...

PyTorch 3.0静训性能断崖预警:当AllReduce延迟>8.3ms或图编译耗时>117s时,你的训练任务已在 silently fail——附实时诊断CLI工具

第一章&#xff1a;PyTorch 3.0静态图分布式训练的静默失效危机全景PyTorch 3.0 引入的 TorchScript 静态图编译机制与 torch.distributed 的深度耦合&#xff0c;在多节点多卡场景下暴露出一类高危静默失效现象&#xff1a;训练进程持续运行、梯度同步无报错、loss 曲线看似收…...

别再手动改daemon.json了!1Panel面板里一键配置Docker国内镜像源(附最新可用源列表)

1Panel面板实战&#xff1a;3分钟搞定Docker国内镜像加速配置 刚部署完1Panel的新用户总会遇到一个经典问题——Docker拉取镜像慢得像蜗牛爬。传统解决方案是手动编辑daemon.json文件&#xff0c;但如今有了更优雅的选择。作为一款现代化服务器管理面板&#xff0c;1Panel将复杂…...