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

正统 C++:避开现代 C++ 弊端,代码易维护还兼容旧编译器!

正统 C++:避开现代 C++“坑”,还能兼容旧编译器!

2016 年 1 月 16 日,本文最初以要点形式发布 在此。下面详细了解一下正统 C++。

什么是正统 C++?

正统 C++(有时也被称为C+)是 C++ 的一个最小子集,它对 C 语言进行了改进,但避免了所谓现代 C++ 中所有不必要的东西。这与 现代 C++ 的理念正好相反。

为什么不用现代 C++?

早在 20 世纪 90 年代末,我们也是当时追求潮流的 C++ 玩家,使用着最新的特性,还劝别人也用。但随着时间推移,我们发现,仅仅因为某些语言特性存在就去使用它们是不必要的,有些我们用过的特性后来被证明并不好(比如 RTTI、异常处理和流),或者会带来不必要的代码复杂性。如果你觉得这是无稽之谈,那就再等几年,你也会讨厌现代 C++ 的(《为什么我不再花时间在现代 C++ 上》,存档的领英文章)。

为什么使用正统 C++?

“在 C++ 内部,有一个更小、更简洁的语言在努力破茧而出。”——比雅尼·斯特劳斯特鲁普

用正统 C++ 规范编写的代码库更易于理解和维护,也能在旧编译器上编译。用正统 C++ 子集编写的项目更容易被其他 C++ 项目接受,因为正统 C++ 使用的子集不太可能违背采用者对 C++ 子集的偏好。

正统 C++ 的 “Hello World”

#include <stdio.h> int main() { printf("hello, world\n"); return 0; }

我应该用什么?

  • 如果代码不需要更多的复杂性,那么类 C 的 C++ 是个不错的起点,不要添加不必要的 C++ 复杂性。一般来说,代码应该让熟悉 C 语言的人都能读懂。
  • 不要做 这种事,在正统 C++ 中,“设计原理” 部分在 “非常简单,而且可用。结束” 之后就应该立即结束。
  • 不要使用 异常处理。
  • 不要使用 RTTI。
  • 不要使用 C 运行时头文件的 C++ 包装(如 <cstdio>、<cmath> 等),而应使用 C 运行时头文件(如 <stdio.h>、<math.h> 等)。
  • 不要使用流(如 <iostream>、<stringstream> 等),而应使用 printf 风格的函数。
  • 除非你不关心内存管理,否则不要使用 STL 中任何会分配内存的部分。更多信息可参考 CppCon 2015:安德烈·亚历山德雷斯库《std::allocator 之于内存分配,就像 std::vector 之于烦恼》 的演讲,以及 为什么许多 AAA 游戏开发工作室不使用 STL 的讨论。
  • 不要过度使用元编程来进行学术性的炫技。适度使用,仅在必要且能降低代码复杂性的地方使用。
  • 对当前 C++ 标准中引入的任何特性保持谨慎,理想情况下,等待下一次标准迭代对这些特性进行改进。例如,C++11 中的 constexpr 在 C++14 中才变得可用(据 Jason Turner 所说,cppbestpractices.com 的策展人)。
  • 不要使用 模块。

使用模块会带来以下缺点:

  1. 需要重写(可能还需要重构)你的代码。
  2. 丧失可移植性。
  3. 模块二进制文件(MSVC 除外)不可移植,所以无论如何都需要为库提供头文件。
  4. 项目构建设置变得更复杂。
  5. 除了最新版本的工具链,其他版本都无法工作(撰写本文时,苹果的模块支持被列为 “部分支持”)。

作为交换,你(普通开发者)能得到以下好处:

  1. 没有任何好处。

现在使用现代 C++ 的任何特性安全吗?

由于编译器、操作系统发行版等对 C++ 标准的采用存在滞后,通常无法立即开始使用新的有用语言特性。一般准则是:如果当前年份是 C++ 标准年份 +5,那么可以有选择地开始使用该 C++ 标准年份的特性。例如,如果标准是 C++11,且当前年份 >= 2016,那么可能是安全的。如果编译代码所需的标准是 C++17,而当前年份是 2016,显然你是在实践 “简历驱动开发” 方法。如果你是在为开源项目这样做,那么你创建的东西可能别人无法使用。

修订历史

更新截至 2025 年 1 月 14 日,正统 C++ 委员会批准有选择地使用 C++20。

  • 2025 年 10 月 19 日 - 添加了关于模块的信息。
  • 2019 年 1 月 16 日 - 添加了关于异常处理的信息。
  • 2018 年 2 月 1 日 - 添加了关于 constexpr 需要多次迭代才能变得有用的信息。
  • 2016 年 1 月 16 日 - 原文发布。

还有其他类似的理念吗?

  • 嵌入式 C++ <https://en.wikipedia.org/wiki/Embedded_C%2B%2B>
  • 名义 C++ http://archive.md/2016.08.07-162105/https://namandixit.github.io/blog/nominal-c++/
  • 理智 C++ http://archive.md/2016.08.07-162220/http://flohofwoe.blogspot.nl/2013/06/sane-c.html
  • 为什么你的 C++ 应该简单 http://archive.md/2017.03.19-055108/https://hacksoflife.blogspot.nl/2017/03/why-your-c-should-be-simple.html
  • C++,不是你的问题,是我的问题 https://web.archive.org/web/20190227061553/https://c0de517e.blogspot.com/2019/02/c-its-not-you-its-me.html
  • “保持 C 风格的简单” 亚历山大·拉德琴科悉尼 C++ 聚会 https://www.youtube.com/watch?v=lTXHOOwfTAo
  • C++ 的一种方言 https://web.archive.org/web/20200521234043/https://satish.net.in/20180302/
  • Defold 引擎代码风格 https://web.archive.org/web/20241003193318/https://defold.com/2020/05/31/The-Defold-engine-code-style/
  • 正统性 - Clang 编译器的插件,可选择性禁用 C++ 语言的特定特性 https://github.com/d-musique/orthodoxy?tab=readme-ov-file#orthodoxy

代码示例

  • 任何能在 C++ 编译器上编译的 C 源文件。
  • DOOM 3 BFG <https://github.com/id-Software/DOOM-3-BFG>
  • Qt <https://github.com/qtproject>(在不使用 RTTI 和异常处理的情况下构建)
  • dear imgui <https://github.com/ocornut/imgui>
  • bgfx <https://github.com/bkaradzic/bgfx>
  • TheForge <https://github.com/ConfettiFX/The-Forge>
  • Oryol <https://github.com/floooh/oryol>
  • Network Next SDK <https://github.com/networknext/sdk>

—— 还有一件事...

我开发 bgfx 的使命是为游戏开发者提供一个跨平台、与图形 API 无关的渲染库,简化游戏在不同平台上的移植过程,确保无缝的性能和兼容性,而不会被特定引擎所束缚。如果你喜欢这篇文章并支持我的使命,请考虑成为 赞助者!❤️

http://www.rkmt.cn/news/1523934.html

相关文章:

  • Steam Achievement Manager:7个高级技巧解锁你的游戏成就管理
  • OpenCoworker与aisuite:桌面AI助手与轻量级Python库助力大语言模型开发!
  • 武当山特区有学籍的武校哪家专业 - GrowthUME
  • 5分钟掌握拯救者工具箱:联想笔记本开源硬件管理的终极实战指南
  • 宇树GO2 ROS2 SDK:让四足机器人开发变得如此简单!
  • 终极罗技鼠标宏指南:3分钟实现PUBG完美压枪控制
  • Steam游戏解锁终极方案:Onekey清单下载器完整指南
  • LiteDB Studio:嵌入式文档数据库的终极可视化解决方案
  • 终极利器:3步掌握暗黑破坏神2存档编辑器的核心价值
  • 梳齿式蓝莓收获机结构设计213(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Armbian系统下,Docker OpenWrt旁路由两种组网方案实测:桥接 vs Macvlan,我最终选了它
  • 从零搭建企业广域网:手把手教你用MPLS VPN替代老旧专线(附避坑指南)
  • 2026奢侈品回收手表回收名表回收|唐山市宝格丽二手首饰回收 优选路北区毓典寄卖行 - GrowthUME
  • MPC823 I2C控制器原理与编程实战:从寄存器配置到缓冲区描述符
  • 2026年西安CPPM采购经理报名费用资料和试听课班期怎么核对?众智商学院官网400冯老师18610089571指南 - 众智商学院职业教育
  • 终于搞懂PMC、MRP和BOM的区别和联系了
  • 深圳西乡塘西新村:破解餐饮油污难题 隔油池养护成合规关键 - GrowthUME
  • 2026湖北民办中职学校深度解析:办学质量评估与选型建议 - GrowthUME
  • Android Studio英文界面太难用?3步切换中文的完整指南
  • MPC8313E DMA与PCI接口实战:门铃机制、链式传输与性能优化
  • Adobe-GenP 3.0终极指南:5分钟快速激活Adobe全家桶的完整教程 [特殊字符]
  • 上传照片要求不能超过200kb怎么处理?2026照片压缩小程序测评,含免费小程序 - 像素测评
  • 2026深圳爱马仕香奈儿LV回收实测,逸程S级全品类回收品牌,950+鉴定师背书 - 逸程
  • 深入解析MPC8272通信处理器:架构、模块与应用实战
  • 深入解析MPC8540 DDR内存控制器:从信号时序到ECC配置实战
  • Windows平台Node.js环境切换的终极方案:nvm-windows实战指南
  • 把「画分镜」当成写代码:用一段结构化提示词让 Image-2 一次生成 9 格脚本
  • 深入解析FlexCAN中断与缓冲区管理:从寄存器到实战应用
  • MPC8272安全引擎AESU与加密通道实战:寄存器配置与调试指南
  • Windows Cleaner:智能化系统优化工具,高效解决C盘空间不足问题