本文最初发布于博客 THENEWSTACK。
图片来自 Unsplash
为了避免与内存相关的 Bug,C++开发人员经常被迫改用Rust。但他们是否还有其他的选择呢?
在九月份的邮件中,第21工作组(成立于 1990 年,由 “对 C++工作感兴趣的、公认的专家 ”组成)发布了一项提案。此后,这项名为“Safe C++扩展“的提案在网上引发了广泛的讨论。
一切都表明,C++社区正在开展一场声势更为浩大的运动,为这门已经有 39 年历史的编程语言探索新的解决方案,以应对人们对内存安全的持续关注。Safe C++提案只是其持续努力的一部分,人们还在不断地提出其他的想法和方法,有些已在讨论中。
这次对话的背景是,编程社区对提升安全代码性的需求日益迫切。因此,新提案 Safe C++首先承认,对 C++的持续批评 “削弱了该语言对新手的吸引力”,但同时也指出,Rust堪称典范的安全模型可以 “成为加强 C++的契机”,并补充说,Rust 长达十年之久的内存安全保证工作为我们指明了方向,并为 Safe C++的设计提供了大量参考信息。
“采用安全专家证明过的安全模式所有权和借用,是一个能够让下一代 C++保持活力的既合理又合时的方法"。
提出解决方案
根据提案,Safe C++的当前版本花了 18 个月的时间来设计和实现。该提案由下面这两位非常敬业的开发人员所撰写:
来自纽约的 Sean Baxter 是一名开发人员,他的职业生涯包括在美国国家航空航天局喷气推进实验室担任了三年半的软件工程师,之后又在英伟达公司(NVIDIA)担任了两年多的研究科学家(参见他在LinkedIn上的个人简介),并创建了一个 C++编译器的替代实现Circle。
来自萨克拉门托的Christian Mazakas是C++联盟的高级工程师。该联盟是一家成立于 2017 年的 501(c)(3) 慈善机构,旨在通过鼓励提交新代码库和语言提案以及赞助教育活动来支持 C++社区。
C++联盟于 9 月份宣布与 Baxter 建立合作伙伴关系,并将其称作是“增加 C++语言内存安全特性的革命性提案”。C++联盟总裁兼执行董事 Vinnie Falco 称,这是 “C++生态系统中的一个重要里程碑,因为对安全代码的需求从未像现在这样迫切”。
那么,他们是如何实现的呢?该提案的一个 “关键部分 ”是用所谓的安全标准库来增强 C++标准库: “通过将这些组件集成到 C++标准库中,确保从一开始编写新代码时就考虑到安全性。“
正如他们的文档所言:”首先是大棒......Safe C++的开发人员被禁止编写可能在生命周期安全、类型安全或线程安全方面导致未定义行为的操作。有时,这些操作会被编译器前段禁止,例如指针运算。有时,这些操作会被编译器中段的静态分析所禁止,防止使用未初始化变量或使用已释放变量的错误,这也是安全模型所有权和借用的使能技术。其余问题,如数组下标越界,则是通过运行时 panic 和终止来解决。“
而“胡萝卜则是一整套的新功能,它们改进了不安全的特性”,包括新的模式匹配和复杂的借用检查(跟踪引用以避免出现 “释放后使用 ”漏洞的可能性)。
改进工具链
对 Baxter 来说,他一直对这个很感兴趣。早在 2019 年,他就创建了Circle,那是一个新的 C++编译器。他说,只需简单地改进下工具链,它就能提供一种成熟的后继者语言所能提供的所有好处。顾名思义,这种方法与现有的 C++代码完全兼容。正是通过 Circle,Baxter 首次为 C++实现了类似 Rust 的借用检查器,即便在那时,Baxter 就已经对 C++代码的长远命运表现出了比较大的兴趣。
2022 年,在宣布推出新版的 Circle 时,Baxter 对那些 C++的诋毁者提出了质疑,称这种语言本身有缺陷/不安全/编译速度慢。“但软件做软件的事,你做你的事,只要努力,就能做出新东西。这里介绍的技术可以扩展 C++工具链,修复语言缺陷,使语言更加安全高效,同时与现有代码资产保持 100%兼容。“
”C++将不仅仅是一种语言,它还将是一个起点,从此编程将向着更安全、更简单、更高效,同时又与现有 C++资产保持互操作的方向发展。“
那么,为什么不干脆让所有人都改用 Rust 呢?新的 Safe C++提案陈述了自己的理由。“对于职业 C++开发人员来说,Rust 是陌生的,再加上互操作工具的限制,要通过在 Rust 中重写关键部分来加固 C++应用程序很难。对于内存安全,为什么不用语言内的解决方案?为什么不能是 Safe C++ ?“
最近,Register 杂志发表的一篇文章回顾了历史,从研究人员到微软Azure首席技术官Mark Russinovich,最后甚至是美国国家安全局和白宫都曾发出过警告。Baxter 承认:"政府最近发出的有关内存安全的警告使整个科技界都在关注这个问题。“
“我做了理论研究,发现有机会利用新工具帮助 C++工程师编写更正确的程序,并消除与安全漏洞关系最大的一类软件缺陷"。
Profiles 有什么变化?
关于改进 C++,这并不是唯一的想法。13 个月前,在 CppCon 大会上,C++的创建者 Bjarne Stroustrup 就对与会者说,C++语言的现状是“一个机会”。他还补充说,从 C++语言诞生之初,类型和资源安全就一直是这门语言的目标。Stroustrup 建议用 profiles(可由编译器进行检查的安全保证规则)来改进该语言。
对于标准 C++基金会(由微软、谷歌和英特尔支持的非营利组织)GitHub 存储库中的 profiles,人们已经有了一些想法。该库有一个由 Bjarne Stroustrup 和 ISO C++标准委员会主席Herb Sutter共同编写的 C++核心指南页面。现在,该页面已经包含了对 “相关规则组”(名为profiles)的引用,其中描述了实现类型安全和边界安全等预期结果的指导原则。
“profiles 主要是供工具使用,但也可供人类参考。我们的观点并不局限于‘Enforcement’一节,那些我们知道如何强制执行的内容;有些观点仅仅是一些愿望,或许可以为某些工具构建者带去一些启发"。
但上周四(10 月 24 日),Baxter 新发表了一篇题为 “为什么Safety Profiles失败了”的论文。
“Safety Profiles"于 2015 年推出,承诺检测现有 C++代码中所有的生命周期安全缺陷。这是一个大胆的承诺。但经过十年的努力,Profiles 未能产生规范、可靠的实现,也未能为 C++安全带来任何实实在在的好处。失败的原因在于其核心设计中有一些错误的前提"。
这里有我论文的草稿:https://t.co/cfY2Vokfbr。
我试图从以下几个方面来分析生命周期安全问题:
1. 别名
2. 生命周期
3. 安全性
C++没有提供任何这些方面的信息。其强化安全性的尝试注定会失败。
— Sean Baxter (@seanbax) 20244年10月24
该论文继续写道,C++源代码 “没有足够的信息来实现内存安全......”,并建议 “将 Rust 的安全模型引入 C++”(也将改善 Rust 和 C++之间的互操作性)。“通过在 C++中扩展所有可以出现在函数声明中的 Rust 结构的表示(如 Rust 枚举、借用和生命周期、ZST、trait 等),公共词汇表类型的数量大大增加。
“C++可以实现内存安全,但不是通过摒弃一切有效的东西,而这正是 Safety Profiles 的作者所做的"。该论文认为,C++必须 “更加明确地表达别名、生命周期和安全属性等”。
合作过程
有些讨论已经在进行,而且可能会有更多的讨论。除了宣布提案外,Baxter 和 C++联盟还宣布,他们正在 “寻求开发人员、研究人员和其他利益相关者的反馈”,相信合作过程 “将有助于完善项目的范围,并确保它能满足 C++生态系统最迫切的需求”。
他们的提案指出:“有了业界的参与,我们就能解决剩余的设计问题。再过 18 个月,我们就能开发出足够强大的语言和标准库,用于主流评估。虽然 Safe C++是对这门语言的一个巨大的扩展,但构建新工具的成本并不高......我们正一起设计 Safe C++标准库和语言扩展。感兴趣的读者可以访问我们的 GitHub 库,了解我们的工作。“
域名“SafeCPP.org”于今年 6 月创建。现在,它会自动将所有访问者重定向到 Safe C++提案的 draft.html 页。
声明:本文为 InfoQ 翻译,未经许可禁止转载。
原文链接:https://thenewstack.io/can-the-safe-c-proposal-copy-rusts-memory-safety/
评论