上下文中的 C++ 安全性
委员会、流程与安全特性
- 许多评论者感到沮丧,因为好的安全想法确实存在,但标准化进展缓慢且不一致(例如,
std::span直到 C++26 才带上.at(),operator[]仍然不做检查)。 - 有人澄清,C++ 委员会主要是对由现有工作实现支持的提案进行认可;它无法单方面“强加”一个新的 C++。
- 向后兼容性和 ABI 稳定性被视为占主导地位的约束,它们阻碍了更深层的安全变更(例如 fat pointers、破坏性语法改动、epochs)。
文化与默认不安全
- 有多个故事提到团队关闭 sanitizer、忽视 ASAN 报告、拒绝使用调试器,并且把越界访问视为只要“不会崩溃”就可以接受。
- 一些人认为这本质上是态度问题:工具已经存在,但许多开发者和组织除非受到强烈激励或惩罚,否则不会使用它们。
- 也有人反驳说,并非所有软件都需要同样级别的加固,但批评者回应称,任何联网应用都可能成为利用链的一部分。
边界检查与性能权衡
- 围绕默认边界检查的争论反复出现:
operator[]应该中止、抛出异常,还是继续保持不检查;安全是否应该默认开启,并提供显式的unsafe_*逃逸口。 - 有人认为实际开销很小(引用系统级测量),而且值得;另一些人强调 HPC/嵌入式工作负载,即使几个百分点的回退也很重要。
- 历史上的借口(“1990 年太慢”)如今被认为不那么成立,但仍有人把性能置于安全之上。
CVE、指标与文件系统竞态示例
- 关于用原始 CVE 数量来比较 C/C++ 和 Rust,存在强烈分歧:严重性不同,而且不同语言社区对什么算 CVE 的标准也不同。
- 例如:一个文件系统 TOCTOU 问题在 Rust 中得到了 CVE 和博客修复;C++ 标准库悄悄修补了类似 bug,但没有提交 CVE,而 C++ 规范把文件系统竞态标记为未定义行为。
- 有人担心 C++ 相关方会通过“管理” CVE 数量而不是修复根本原因;也有人说即便没有 CVE,这个问题也被负责地处理了。
与 Rust 和其他语言的比较
- 许多人认为 Rust 是一个质的飞跃:默认内存安全、封装的
unsafe、更好的线程安全保证,以及把安全视为首要目标的文化。 - 反驳意见:Rust 仍然有 CVE;许多 Rust crate 使用
unsafe(通常是为了 FFI);纯安全 Rust 在没有间接层的情况下难以处理某些数据结构(arenas、Rc/Arc、索引)。 - 有人强调,内存安全只是众多漏洞类别之一;内存安全语言仍然会有逻辑 bug、注入、机密处理等问题,但其他人认为,消除一大类 bug 仍然是“值得拥有的问题”。
政府、产业压力与 C++ 的未来
- 近期政府和大型厂商报告呼吁转向内存安全语言,被视为重要背景;有些人把这篇文章解读为一种防御性回应。
- 争论在于:C++ 是否能通过非破坏性变更和工具,现实地达到与内存安全语言“平价”,还是需要激进且破坏性的转变(epochs、安全子集,或“Typescript-for-C++”式方案)。
- 许多人认为遗留 C++ 还会持续几十年,因此即便新项目迁移到 Rust、Go 等语言,更好的工具和更安全的模式仍然很重要。
认知负担与项目选择
- 多篇帖子把现代 C++ 描述为在认知上令人疲惫:语法复杂、模板错误严重、重叠特性太多,以及微妙的 UB。
- 一些人说自己仍然使用 C++ 只是因为遗留代码、生态或领域惯例(HPC、游戏引擎),否则他们会更愿意选择 Rust 或其他语言。
- 整体情绪是:C++ 可以在边缘上变得更安全,但对于新的绿色场景工作,许多评论者如果可以会避免使用它。