C++的两个派系之争

C语言与CPP编程 2025-04-01 09:00


转自:InfoQ -核子可乐、冬梅
作者:Mond

关于 C++ 的未来该向何处去,似乎有着很多争论甚至是激烈对抗。无论是 Reddit 上的小打小闹,还是官方 C++ 标准委员会中的严肃讨论,都免不了要陷入立场之争、派系之争。这已经成为无法回避的客观现实。

C++ 的当前处境

目前来看,C++ 阵营处于如下状态:C++ 的演进工作组(EWG)刚刚就采用 P3466 R0 达成共识——即应当重新确认未来 C++ 演进的设计原则:

  • 这意味着拒绝 ABI 破坏,保留与 C 以及此前 C++ 的链接兼容性。

  • 这也意味着拒绝“病毒注释”(例如不设全生命周期注释)。

  • 这大大强调了对一系列不兼容目标的处置,即拒绝 ABI 破坏以及零开销原则。

  • 无论是好是坏,这都是对当前 C++ 语言演进轨迹的强化。

但与此同时,在 C++ 的发展道路上也面临着一系列阻碍,包括美国政府机构(网络安全与基础设施安全局(CISA)、美国国家安全局(NSA)以及白宫)希望人们停止使用 C++,美国政府各个部门均已发布文件、报告和建议,警告技术行业不要使用内存不安全的语言。

各大科技巨头也有弃 C++ 转投入 Rust 之势。

不久前,在微软工作了 22 年的 ISO C++ 委员会主席 Herb Sutter 也离开了微软,成为 Citadel Securities 的技术研究员。有消息称微软明显正在使用 Rust 重写其核心库。早在 2022 年,Microsoft Azure 首席技术官 Mark Russinovich 就敦促科技行业放弃 C/C++。“说到语言,现在是时候停止用 C/C++ 启动任何新项目,并在需要非语言的场景中使用 Rust,”他说。“为了安全和可靠性,行业应该宣布这些语言已弃用。”

谷歌曾在 2021 年就发文称正在全力推动 Rust。谷歌表示:“Android 平台代码的正确性是每个 Android 版本安全性、稳定性和质量的首要任务。C 和 C++ 中的内存安全错误仍然是最难解决的错误来源。我们投入了大量的精力和资源来检测、修复和缓解此类错误,这些努力有效地防止了大量错误进入 Android 版本。然而,尽管付出了这些努力,内存安全错误仍然是稳定性问题的主要因素,并且始终占 Android 高严重性安全漏洞的 70% 左右。而 Rust 通过结合使用编译时检查来强制执行对象生存期 / 所有权,并使用运行时检查来确保内存访问有效,从而提供内存安全保障。在提供与 C 和 C++ 相当的性能的同时,还实现了这种安全性。” 实际上已经开始开发 C++/Rust 双向互操作工具。

工具地址:https://github.com/google/crubit

AWS 也正在重度使用 Rust。AWS 在官微上发文称,“Rust 带来了完善的工具、强大的包管理器 (Cargo),也许最重要的是——一个快速增长且充满热情的开发者社区。随着 Rust 越来越受欢迎,越来越多的知名组织,包括 AWS,将其用于性能和安全性是首要关注点的关键应用程序。例如,Amazon S3 利用 Rust 尝试以个位数毫秒的延迟返回响应。用 Rust 编写的 AWS 产品组件还包括 Amazon CloudFront、Amazon EC2 和 AWS Lambda 等。

此外,臭名昭著的 Prague ABI 投票已经开始(即「C++23 不会破坏 ABI,但不清楚未来是否变化」)。据称谷歌大幅降低了其在 C++ 开发流程中的参与度,转而开发自己的 C++ 后继语言。他们甚至专门发布总结,概述了在尝试改进 C++ 时遇到的所有问题。这也为 C++ 风雨飘摇的未来多蒙上一层阴影。

多年以来,人们竭尽全力参与 C++ 标准委员会流程,但却最终被彻底驳回的故事已经广为人知,并在整个社区中流传。(哪怕是已经在 C 中得到实现的功能也不例外。)模块设计仍未实现,C++ 什么时候才能拥抱模块化?

基于以上种种,不免让人对 C++ 的未来表示担忧。事实上,很多人对 C++ 委员会对于混乱现状的掌控能力已经失去了信心。

困在两种文化冲突之中

人们似乎正在寻求其他解决方案。

比如谷歌自 ABI 投票以来,就明显对 C++ 委员会的“流程”失去了信心。这并不是对语言本身失去信心,毕竟谷歌拥有世界上最大的 C++ 代码库之一,而且一直为其提供着非常好的维护服务。所谓失去信心,主要是不看好该语言在面对来自不同角度的压力(包括潜在政府法规、竞争语言的冲击、关键参与者对于更高性能以及更佳安全保障的规划等)时能否保持住不断演进的能力。

那么问题的根源是什么?C++ 为什么会变得这么……食古不化?

这个问题并不难回答,只消看看 Herb Sutter 在他关于配置文件的文章就能窥得一二:

“我们必须尽量减少对现有代码的变更需求。对于现有代码中已经存在的应用,数十年的经验一直表明,大多数拥有大型代码库的客户不能、也不会为了满足严苛规则而更改哪怕1%的代码行。除非监管要求强迫他们这样做,否则即使是出于安全原因也无法推动这方面举措。”


——Herb Sutter

这话说得……但神奇的是,人们似乎又对此见怪不怪。

现在让我们跟 WG21 成员页面上 Chandler Carruth 的小记做一番对比:

“我执掌了基于 Clang 构建的 C++ 工具与自动重构系统的设计工作,其现在属于 Clang 项目的组成部分……在谷歌内部,我领导了将基于 Clang 的自动重构工具扩展到我们整个代码库(共涉及超过 1 亿行 C++ 代码)的努力。我们可以在 20 分钟之内分析并对整个代码库执行重构。”

看到了吗,人家好像愿意做变更。

而遗憾的是,自动化迁移工具也是 C++ 阵营目前唯一拿得出手的应用案例了。

基本上,我们看到了两大截然不同的 C++ 用户派系之间的冲突:

  • 灵活、现代且能力更强的科技企业,清楚意识到自己的代码是一种资产。(请注意,这里指的并不只有大型科技企业,任何理智的 C++ 初创公司也都会站在这一边。)

  • 除此之外的所有老牌企业,都仍在为代码缩进之类的细节而争吵。部分年轻工程师甚至需要恳求管理层允许他们设置 linter。

相信未来一定会出现一支能够优雅处理迁移,并且立足版本化源代码构建其 C++ 技术栈的团队,但绝不会是目前仍强行使用 1998 年古老预建库的团队。

当然,这在实践中会是一个渐变的过程。我只能想象,要想将大型技术代码库从可怕的混沌转化成具备一定可管理性、可构建性、经过 lint 分析、拥有正确版本控制的改良形态,必然要付出无数汗水、泪水、成本甚至是牺牲。

事后看来,我们当然可以轻飘飘地认为这一切都是历史大势的必然:谷歌等巨头的需求(即使用高度现代化的 C++ 代码、建立自动化工具与测试以及现代化基础设施)明显与其(非常强烈的)向下兼容意愿之间存在脱节

我们甚至可以大胆地讲,统一无方言的 C++ 概念似乎在多年之前就已经消亡。目前我们至少面对着两条主要 C++ 发展路线:

  • 任何稍微现代的 C++,可能至少是从 C++17 开始。它们支持 uniqe_ptr, constexpr, lambdas 还有 optional。一切都可以从版本化的源代码构建,使用某种专用、干净且统一的构建流程,该流程至少要比原始 CMake 稍微复杂一些,而且只要认真观察应该就能顺利起效。其还具备某种静态分析器、格式化程序、linter 等。总之,要支持一切有助于保持代码库干净和现代的协议。

  • 不符合以上特征的其他产物。比如那些长期运行在中等规模银行里那古老、布满灰尘的服务器当中的 C++ 项目。这些 C++ 往往依赖于某些极其陈旧的编译代码块,而且对应的源代码已经丢失,且无法联系到其原始作者。还包括一切部署在微型服务器上的 C++,要在其他环境下正常启动,工程师们往往需要一个月时间才能厘清其中的所有隐式依赖项、配置和环境变量。这些就是被广泛归类为成本中心的遗留代码库。

大家会注意到,两派最大的分歧并不在于 C++ 本身,而在于依托工具或者其他手段以干净且定义明确的方式,立足版本化源代码进行构建的能力。理想情况下,我们甚至并不需要记住前一个人设置的标记或者环境变更,即可顺畅部署而不致引发崩溃。

很多人会强调,这类生态工具并不在 C++ 标准委员会的职责范围之内。这话也没错,但工具之所以不在他们的职责范围内,是因为 C++ 标准委员会放弃了这份责任(他们只专注于 C++ 语言的规范,而非具体实现)。当然,这跟 C++ 语言本身的设计有关,属于遗留问题,我们也不能过多责怪。总之如今的 C++ 已经成为一套用于统一不同实现的囊括性标准。

但相比之下,如果要说 Go 有哪件事做得最为正确,那就是它证明了工具非常重要。相比之下,C++ 就像是来自史前时代、来自 linter 被发明出来之前。C++ 没有统一的构建系统,甚至没有勉强能算统一的包管理系统,因此解析和分析起来都极其困难(这对配套工具来说很糟糕),每一次更改都会带来一场艰苦卓绝的折磨和对抗。

这两个派系之间还存在着巨大且仍在不断恶化的裂痕。老实说,我认为这种裂痕不可能很快消失。C++ 委员会似乎致力于(当然,这已经是很高情商的说法了)保持向下兼容性,甚至愿意为此不计成本。

后果是什么?

于是配置文件机制就成了现在这个样子:安全配置文件的意义并不在于帮助已经迈向现代、精通开发技术的 C++ 企业解决问题,它们的目标是在实现改进的同时,保证无需对旧有代码做出任何更改。

模块机制也是如此,开发者应该可以“仅”将 header 文件作为模块导入,且不致因此引发任何类型的向下兼容性问题。

当然,人人都希望那种可以直接插入即生效,且无需对旧有代码做出任何更改的功能。但很明显,这些功能的设计(也是最重要的特征)是以“遗留 C++ 代码”为目标的。而任何需要对遗留 C++ 进行功能迁移的演进在 C++ 委员会都完全行不通,毕竟正如 Herb Sutter 所说,绝对不能指望人们愿意承担这份迁移负担。

这就是我在查阅 C++ 讨论资料时最鲜明的印象:阵营中分为两大派系,一派是现代 C++,另一派则是遗留 C++。两大派系之间存在着激烈分歧,而许多文章都只针对其中某一特定群体的需求撰写而成。

C++ 委员会正试图防止这种分歧进一步扩大。可能也正因为如此,Sean Baxter 在 Safe C++ 方向上做出的任何尝试都注定徒劳无功。这将是一波颠覆性的变革,可能会创造一种全新的 C++ 编写方式,可惜变不得。

当然,这里还有另外一个问题,就是可能某位 C++ 标准委员会成员特别特别固执,不接受任何贡献者在发展取向上的异见。

我绝不是要指责任何人,但我曾经多次听说 C++ 委员会搞双重标准,比如“如果您希望该提案获得批准,希望您能在几款工作编译器上进行全面、有效的实现,但我们仍乐于支持某些未经有效概念验证的大型项目(例如模块和配置文件机制)。”

如果情况继续发展下去,那么我严重怀疑 C++ 阵营的彻底分裂恐怕就在眼前。

而这一切,甚至还没算上破坏 ABI 兼容性所导致的诸多麻烦和问题。

  1. 如果大家对此持怀疑态度,也可以将其理解为对于 Rust“全生命周期注释”和 Sean Baxter“Safe C++”提案的明确否定。哪怕更乐观地看,这也至少代表着该委员会根本不关心对现有代码的重构需求。

  2. “你不会为自己不用的东西付费。”本质上,现有 C++ 功能只在我们积极使用时才会影响到运行时性能。而这显然跟稳定的 ABI 有所抵触,毕竟稳定 ABI(大家可以将其理解为 C++ 中的一项特性)会排除某些性能改进措施。

  3. 我认为 Carbon 比大多数人印象中要有趣得多。后续我可能会撰写一篇专门的讨论文章。

  4. 那么 C++ 阵营真的在分崩离析吗?这要看从哪个角度理解。如果从 C++ 代码存续的角度看,那么并不会,至少原有的 C++ 成果还将长期存在。

  5. 请注意,我说的是 C++ 阵营本身,与之对应的各种不同编译器以及编译扩展完全是另一个概念。

网友怎么看?

该帖子在 Reddit 社区中引发了诸多讨论。ID 名为 ravixp 的 Reddit 用户对上述观点表示认同。

“这段话引发了我的强烈共鸣,原因是我曾亲眼见证了一个庞大的 C++ 代码库,在历经数十年的开发过程中,如何从“传统”逐步过渡到“现代”C++。这一转型并非一蹴而就,而是由不同团队在不同时间和以不同速度独立决定的,至今仍在持续进行中。任何新的代码现代化计划都不得不面对这样一个现实:代码库中的各个部分起始的现代化水平参差不齐。


然而,现代化的代价高昂。这里所指的现代 C++,并不仅仅是编写方式上的差异,它还意味着可能需要重建整个工具链上层结构,以使代码符合现代标准,并拥有一支能够紧跟 C++ 发展步伐的工程团队。

ID 名为 KittensInc 的 Reddit 用户解释了美国禁止 C++ 的合理性,因为美国政府认为 C++ 代码库正成为负担,他们倡导避免重蹈覆辙以减少错误。缓冲区溢出等问题的预防变得重要,导致企业要求第三方审计以确保代码质量。企业面临现代化改造的抉择,否则可能面临倒闭风险,而采用现代开发实践的企业能更轻松应对。

“我并不惊讶于未来几年这种动态可能会发生变化。遗留的 C++ 代码库正迅速成为一项沉重的负担。美国政府已经认识到,通过采取不同的设计决策可以有效避免一类错误的发生,并正在积极倡导避免重蹈覆辙。我认为,相关责任人只是时间问题,他们终将跟上这一变革的步伐。


如果我们认为缓冲区溢出等问题是完全可以预防的,那么当这类问题成为安全事件的根源时,黑客攻击、勒索软件、数据泄露的保险拒赔也将变得合乎逻辑。在这种背景下,企业会愈发要求软件供应商提供第三方代码库的 linting 审计,以确保代码质量。

但也有人认为,C++ 代码库的安全性不取决于其现代或遗留属性。90 年代 C++ 库注重安全性并多用运行时检查,而现代 C++ 则减少运行时检查,将更多内容纳入类型系统,未定义行为用于优化。

“安全性的实现与 C++ 代码库是现代还是“遗留”并无直接关联。事实上,在 90 年代,流行的 C++ 库在开发时普遍注重安全性,并广泛采用了运行时检查来确保代码的正确执行。在当时,未定义行为并非被视为编译器可以对代码做出严格假设并执行激进优化的手段,而是被视为一种在不同平台和实现之间实现灵活性的合理方式。


然而,进入 21 世纪初期,“现代”C++ 的发展方向发生了转变,决定减少运行时检查,并尝试将所有内容纳入类型系统中。对于那些无法通过静态验证的内容,它们被归类为未定义行为,编译器则可以根据优化需求进行自由处理。

原文链接:

https://herecomesthemoon.net/2024/11/two-factions-of-cpp/

推荐阅读  点击标题可跳转

1、C++训练营,来了!

2、HarmonyOS 学习资料分享(无套路免费分享)

我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会

加个微信,打开另一扇窗

感谢你的分享,点赞,在看三  

C语言与CPP编程 C语言/C++开发,C语言/C++基础知识,C语言/C++学习路线,C语言/C++进阶,数据结构;算法;python;计算机基础等
评论
  • 记得是1989年在中美合资企业工作时,质检部任职,一次清理寿命实验后不要了的产品时,看到即将扔掉的有好有坏的产品中一个自己经手过的还可以使用的万用表,就留了一个,拿回家使用,都正常,后来,用的少了,放在柜子里,没有拿出电池,时间长了,电池泄露,腐蚀的一塌糊涂!做了清除,这是2017年的事了。这是2017年当时拆开来的状况:用酒精做了仔细的清洗,接下来就想着到哪儿找到可以利用的电池极片呢?买也不容易,总想着废物利用,手头有其它废弃的产品上拆下了保留着的,都不适用,反正不急。正好家人我们要外出一段时
    自做自受 2025-06-24 22:57 226浏览
  • 电磁铁损坏通常由电气、机械、环境和操作等多方面因素共同导致。电气系统异常是zui常见的原因,包括电压超标和绝缘失效。电压偏离额定值15%以上容易造成线圈过热烧毁,而潮湿环境则会导致绝缘电阻骤降,引发击穿故障。机械结构问题也不容忽视,铁芯卡滞、异物堵塞以及超负荷运行都会加速部件磨损,影响电磁铁寿命。环境因素对电磁铁的影响主要体现在温湿度和散热条件上。高温环境会加速绝缘材料老化,潮湿则可能导致非防水型号的性能下降。此外,散热设计缺陷或连续通电时间过长都会使线圈温度异常升高。操作和维护不当同样会引发故
    锦正茂科技 2025-06-23 11:11 377浏览
  • 一、引言随着汽车新四化“电动化、网联化、智能化、共享化”全面推进,几乎每一项新技术的诞生都离不开汽车电子的身影。其中,电子控制单元(Electronic Control Unit,ECU)作为汽车电子控制系统的核心。与传统ECU相比,采用AUTOSAR(AUTomotive Open System ARchitecture,汽车开放系统架构)这种分层架构,极大降低了汽车嵌入式系统软、硬件耦合度。图1 传统软件架构与AUTOSAR架构对比此外,随着国内新能源汽车相关控制器正向开发需求的增长,AUT
    康谋 2025-06-25 10:10 75浏览
  •  汽车轮胎质量,轮胎胎压,等等,关系到汽车行驶安全,做车人,开车人生命安全,汽车轮胎胎压关系到汽车能否正常行驶,所以时刻监测胎压各种参数非常重要,下面我们对一款胎压监测传感器产品进行拆解和分析:  胎压监测传感器产品技术数据和外观图片介绍如下:胎压监测传感器技术数据如下:电池寿命:≥6年;工作温度:-40℃--+105℃;储存温度:-40℃--+125℃;工作湿度:<90%;频率:314.95MHz&433.92MHz;压力监测范围:0-800kpa;
    开发工匠 2025-06-25 12:07 63浏览
  • 在智能制造浪潮席卷全球的今天,MES系统(制造执行系统)作为连接企业管理层与车间生产层的“神经中枢”,其重要性日益凸显。它能有效打通信息孤岛,实现生产全流程透明化、可控化与智能化,是企业迈向“数字化智造”的核心引擎。面对众多国内厂商,如何选择最适合的MES系统?本文将为您揭晓综合实力领先的五大国内MES厂商,并提供实用的选型策略。 国内五大MES系统厂商综合实力排名 1.  盘古信息l 核心优势:盘古信息IMS智能制造系统,通过智能柔性计划排程系统,实时展
    盘古信息IMS 2025-06-24 16:47 148浏览
  • 摘要核工业安全监测对压力传感器的精度、稳定性及抗极端环境能力提出了严苛要求。石英谐振压力传感器凭借其基于石英晶体压电效应的独特工作原理,在高精度测量、抗辐照、宽温域适应性等方面展现出显著优势。本文系统解析石英谐振压力传感器在核工业中的核心应用场景,包括反应堆压力容器监测、管道泄漏检测及放射性物质运输监控,并结合晨穹石英谐振压力传感器的技术特性与实际案例,论证其在核安全领域的不可替代性。研究表明,晨穹 RPS01 系列石英绝压压力芯体通过全金属密封封装、双通道温度补偿及 AI 自校准算法
    传感器晨穹 2025-06-23 10:43 335浏览
  • 一、引言自5G正式商用以来,全球通信产业经历了前所未有的变革。5G以其超高带宽、超低时延、海量连接的能力,使得智能制造、自动驾驶、AR/VR、物联网等新兴产业得以快速落地。但随着5G的广泛应用,其在实际部署过程中仍面临一系列挑战:网络覆盖有限、边缘性能不足、上行能力偏弱等问题日益凸显。为解决这些瓶颈并为6G的演进奠定基础,3GPP于Rel-18阶段提出了“5G Advanced(5G-A)”标准。5G-A不仅是5G的增强版本,更是迈向6G的关键过渡技术,其将深度融合通信、感知、智能、控制、安全等
    用户1750544933504 2025-06-22 21:15 8170浏览
  • 射频同轴连接器材料领域近年来取得显著突破,主要体现在导体、绝缘介质和结构件三个方面。在导体材料方面,高强度铜铍合金的应用大幅降低了信号失真,其热稳定性提升至175℃,特别适合毫米波连接器使用。纳米晶合金的引入使得外壳厚度缩减至0.35mm,同时保持you异的电磁屏蔽性能,为微型化设备提供了可能。绝缘材料方面,交联PEEK等高温聚合物可耐受300℃高温环境,PTFE微粉注塑技术则实现了超薄绝缘层的低损耗传输。复合绝缘结构的一体化成型设计不仅提升了性能,还显著缩短了生产周期。结构件创新包括轻量化航空
    锦正茂科技 2025-06-25 10:02 53浏览
  • 要有效预防电磁铁损坏,需要从电气防护、环境控制、操作规范和定期维护四个方面采取综合措施。在电气防护方面,要严格控制工作电压,确保其与额定值的偏差不超过±15%,对于高压电磁铁还需加装短路保护装置。同时要做好绝缘保护,shou次使用前必须测量绝缘电阻,在潮湿环境中要增加检测频率。环境控制同样重要,要根据工作环境的温湿度条件选择合适的电磁铁型号,ji端环境下要采取特殊防护措施。运输过程中要做好缓冲包装,避免机械损伤。操作时要注意控制通电时间,监测线圈温度,避免超负荷运行。多台电磁铁同时使用时,要保证
    锦正茂科技 2025-06-23 11:35 417浏览
  • 一、 平流层超压气球:极端环境下的监测挑战  平流层超压气球长期悬浮于18-40公里高空,持续承受-70℃至+85℃的剧烈温变、不足地面10%的低压环境(30km高度约10hPa)及强宇宙辐射。传统MEMS压阻传感器在此环境下易出现零点漂移、灵敏度衰减,导致高度控制失准或科学数据失真。  典型案例:2021年印尼弗洛雷斯海7.3级地震监测中,平流层气球需在3000公里外检测次声波引发的微帕级压力波动——相当于海平面气压的百万分之一。此场景对传感器的分辨率与抗干扰能力
    传感器晨穹 2025-06-23 13:58 490浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦