C++ 头文件优化
C++ 是一种灵活的语言,所以需要一种积极的方法来分析和减少编译时依赖。一种常见的达到这个目的的方法是,将依赖从头文件里转移到源代码文件里。实现这个目的的方法叫做提前声明。
简而言之,这些声明告诉编译器某个函数接受和返回哪些参数,而具体的定义则规定了具体的行为。让我们根据下面两种规则来改进编译时长并减少可移植性问题,并且使用 include-what-you-use 这种自动应用这些规则到你的代码库的工具。
1、提前声明类型以加速编译速度
为了改进编译时间,尽可能地用提前类型声明来代替#include 指令。例如:
#include <iostream> #include "a.hpp"
#include "b.hpp"class MyClass
{A a_; B* b_;public:B& foo(std::string arg);
};std::ostream& operator<<(std::ostream& out, const MyClass& obj);
编译器如果需要知道它的大小或者接口,那么只需要知道它的类型的定义。而对于B 来说则不是,任何类型的指针或者引用的大小都是一样的。所以这里的 include可以被提前声明替代。
编译器也不需要知道 std::string 和 std::ostream 的类型,因为它们是模板(可能带有其它未知的默认的模板类型参数),因此我们不能提前声明它们。幸运的是,头文件 为 std::ostream 提供了提前声明。即使std::ostream 的定义是需要的, 仅仅提供了它的定义,而没有输入流或者是 std::cin,std::cout 等等。
改进的文件仅需要以下 include 指令和提前声明:
#include <iosfwd>
#include "a.hpp"
class B;
</code></pre>
这可以让生成的文件小很多。
原则:尽可能使用类型提前声明,但是有外部类型的时候需要特别注意。
2、可移植性问题
如果头文件 A 包含了头文件 B,那么你在包含头文件 A 的时候也会获得 B 的定义。这可能会引起一些细微的关于标准库的问题。除了某些例外,并没有定义哪些头文件包含了哪些。
为了改进编译时间,当需要某些特性的声明时,很多编译器实现包含了一些私有头文件而不是超大的公有头文件。所以当你(意外地)依赖某些间接包含的头文件,你的代码可能因为没有包含某些头文件而无法在别的编译器上成功编译。
这也是前一个例子里讲到的:代码没有包含 string 头文件。在我的平台上这段代码依然可以编译,因为 stream 头文件隐式地包含了,但在别的平台则不一定。
原则:将你要用到的头文件包含进来。如果你需要一个声明,包含相应的头文件。即使最后你的代码里有重复的包含指令,多谢头文件guard 指令,这也没什么问题。
3、Include-what-you-use
好消息是你不用自己手动来执行这两条原则。有一个对应的工具,include-what-you-use(IWYU):https://include-what-you-use.org
这是一个 Google 开发的基于 clang 的工具,用于执行这两个原则:尽可能地将包含指令替换为提前声明,如果依赖简介包含则添加相应的包含指令。
从源代码编译或者从网上下载预编译二进制文件后,你可以轻松地将它与 make 或者 CMake 一起使用。如果使用 make,你只需要将 CXX 变量设置为 IWYU,如果是 CMake 则设置好 CMAKE_CXX_INCLUDE_WHAT_YOU_USE 选项。请查看它们的文档获取更多详细信息。你也可以手动执行,它接受跟 clang 一样的参数。
然后它会给你列出将会对每个文件做出的更改。例如根据我们之前举例的文件,它会得出如下结果:
header.hpp should add these lines:
#include // for string
class B;
header.hpp should remove these lines:
– #include “b.hpp” // lines 6-6
The full include-list for header.hpp:
#include // for ostream
#include // for string
#include “a.hpp” // for A
class B;
除此之外还有一个 python 脚本 fix_includes.py。如果你将 IWYU 的输出作为参数给它执行,它会将这些更改立即执行。
原则:偶尔将 IWYU 运行于你的代码。它会改进编译时间和解决可移植性问题。
4、30倍的超快编译加速是什么样的
提前声明只能提供有限的改进。现在越来越多的公司面临着在高峰时段增加计算能力的需求和更快地响应市场的压力。现在,我们可以在高峰时期进行繁重的编译任务,并且加速你的软件开发时间而不需要改变代码或者增添额外硬件。
通过将任务分布在网络中的本地机器或者是虚拟机上,并且无缝地运行,Incredibuild 的创新解决方案可以为耗时的任务进行加速,例如编译、测试和其它。
欢迎点击了解 Incredibuild 加速 C/C++ 构建编译的解决方案,并获取试用 License!
相关文章:

C++ 头文件优化
C 是一种灵活的语言,所以需要一种积极的方法来分析和减少编译时依赖。一种常见的达到这个目的的方法是,将依赖从头文件里转移到源代码文件里。实现这个目的的方法叫做提前声明。 简而言之,这些声明告诉编译器某个函数接受和返回哪些参数&…...

DataRockMan洛克先锋OZON选品工具
随着全球电子商务的飞速发展,跨境电商平台已成为越来越多企业和个人追逐市场红利的重要战场。在众多跨境电商平台中,OZON以其独特的市场定位和强大的用户基础,吸引了无数卖家的目光。然而,如何在OZON平台上成功选品,成…...
【MySQL精通之路】全文搜索(9)-全文解析器-MeCab
主博客: 【MySQL精通之路】全文搜索功能-CSDN博客 目录 1.介绍 2.安装MeCab Parser插件 3.创建使用MeCab分析器的FULLTEXT索引 4.MeCab Parser空间处理 5.MeCab分析程序停止字处理 6.MeCab Parser术语搜索 7.MeCab分析程序通配符搜索 8.MeCab语法分析器短语…...

【工具】 MyBatis Plus的SQL拦截器自动翻译替换“?“符号为真实数值
【工具】 MyBatis Plus的SQL拦截器自动翻译替换"?"符号为真实数值 使用MyBatis的配置如下所示: mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl调用接口,sql日志打印如下: 参数和sql语句不…...

RT-DETR:端到端的实时Transformer检测模型(目标检测+跟踪)
博主一直一来做的都是基于Transformer的目标检测领域,相较于基于卷积的目标检测方法,如YOLO等,其检测速度一直为人诟病。 终于,RT-DETR横空出世,在取得高精度的同时,检测速度也大幅提升。 那么RT-DETR是如…...

OrangePi Kunpeng Pro开发板初体验——家庭小型服务器
引言 在开源硬件的浪潮中,开发板作为创新的基石,正吸引着全球开发者的目光。它们不仅为技术爱好者提供了实验的平台,更为专业开发者带来了实现复杂项目的可能性。本文将深入剖析OrangePi Kunpeng Pro开发板,从开箱到实际应用&…...

AquaCrop农业水资源管理,模拟作物生长过程中水分的需求与消耗
AquaCrop是由世界粮食及农业组织(FAO)开发的一个先进模型,旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理,特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…...
爬虫之re数据清洗
文章目录 一、正则【Regular】二、重要语法1、获取内容: 左边(.*?)右边2、替换数据: re.sub(源数据|源数据, 目标数据, 字符串) 一、正则【Regular】 概念: 根据程序员的指示, 从<字符串>中提取数据 结果: 列表 使用频率: 正则跟xpath相比, 正则是弟弟 二、重要语法 …...

惯性动作捕捉与数字人实时交互/运营套装,对高校元宇宙实训室有何作用?
惯性动作捕捉与数字人实时交互/运营套装,可以打破时空限制,通过动捕设备写实数字人软件系统动捕设备系统定制化数字人短视频渲染平台,重塑课程教学方式,开展元宇宙沉浸式体验教学活动和参观交流活动。 写实数字人软件系统内置丰富…...

Leecode---栈---每日温度 / 最小栈及栈和队列的相互实现
栈:先入后出;队列:先入先出 一、每日温度 Leecode—739题目: 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温…...

Linux系统编程——动静态库
目录 一,关于动静态库 1.1 什么是库? 1.2 认识动静态库 1.3 动静态库特征 二,静态库 2.1 制作静态库 2.2 使用静态库 三,动态库 3.1 制作动态库 3.2 使用动态库一些问题 3.3 正确使用动态库三种方法 3.3.1 方法一&…...
json formatter哪个好用
在众多的JSON Formatter工具中,确实有几个相当出色的选择,它们各自拥有独特的特点和优势,可以满足不同用户群体的需求。下面就来为大家推荐几个好用的JSONFormatter工具: 1. JSON Formatter & Validator:这款工具…...
react的hooks是什么意思
React Hooks 是 React 16.8 版本引入的一个新特性,它允许你在不编写类组件的情况下使用状态和其他React特性。Hooks使得函数组件变得更加灵活和强大,因为你可以在其中添加状态逻辑、生命周期方法以及其他React功能。 在传统的React类组件中,…...
AVFrame相关接口(函数)
分配和释放 分配 AVFrame AVFrame *av_frame_alloc(void); 分配一个新的 AVFrame 并返回一个指向它的指针。返回的 AVFrame 需要手动释放。 释放 AVFrame void av_frame_free(AVFrame **frame); 释放由 av_frame_alloc 分配的 AVFrame。这个函数会释放帧的数据并将指针设为 …...

低代码与人工智能的深度融合:行业应用的广泛前景
引言 在当今快速变化的数字化时代,企业面临着越来越多的挑战和机遇。低代码平台和人工智能技术的兴起,为企业提供了新的解决方案,加速了应用开发和智能化转型的步伐。 低代码平台的基本概念及发展背景 低代码平台是一种软件开发方法&#x…...
嵌入式测试基础知识
1.白盒测试也称为结构测试,主要用于检测软件编码过程中的错误。 2.黑盒测试又称为功能测试,主要检测软件的每一个功能是否能够正常使用。 3.软件测试流程:根据测试需求编写测试计划、方案,测试用例,做测试分析&#…...

基于网关的ip频繁访问web限制
一、前言 外部ip对某一个web进行频繁访问,有可能是对web进行攻击,现在提供一种基于网关的ip频繁访问web限制策略,犹如带刀侍卫,审查异常身份人员。如发现异常或者暴力闯关者,即可进行识别管制。 二、基于网关的ip频繁访…...

GSM信令流程(附着、去附着、PDP激活、修改流程)
1、联合附着流程 附着包括身份认证、鉴权等 2、去附着流程 用户发起去附着 SGSN发起去附着 HLR发起去附着 GSSN使用S4发起去附着 3、Activation Procedures(PDP激活流程) 4、PDP更新或修改流程 5、Deactivate PDP Context 6、RAU(Routeing Area Update)流程 7、鉴权加…...

OAK相机如何将 YOLOv10 模型转换成 blob 格式?
编辑:OAK中国 首发:oakchina.cn 喜欢的话,请多多👍⭐️✍ 内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。 Hello,大家好,这里是OAK中国,我是Ashely。 专…...

【Python】解决Python报错:AttributeError: ‘class‘ object has no attribute ‘xxx‘
🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...