“如果我们必须用对底层的绝对掌控来换取物理极限的性能,那么 C++ 依然是这个星球上无可替代的语言。”
嘉宾| David Sankel 采访 | 吴咏炜
责编|梦依丹
出品 | CSDN(ID:CSDNnews)
在 Rust 强势崛起、AI 编程重塑开发范式的今天,C++ 这座历经四十载风雨的编程大厦,似乎正面临着前所未有的生存拷问。
内存安全漏洞是否真的无解?
AI 生成的代码究竟是福音还是隐患?
当“未定义行为”从优化的基石变为安全的梦魇,C++ 标准委员会又将如何应对?
带着这些尖锐而深刻的问题,在 2025 全球 C++ 及系统软件技术大会的采访间,奇点智能研究院首席技术咨询师吴咏炜与 Adobe 首席科学家、C++ 标准委员会资深委员 David Sankel 展开了一场直击痛点的深度对话。
左:吴咏炜,右: David Sankel
如有兴趣观看完整视频,可在文末获取
David Sankel 没有回避任何一个敏感话题。从揭示“新代码比旧代码更脆弱”的反直觉真相,到坦陈 C++ 在工具链生态上被 Rust“降级打击”的无奈,再到对 AI 编程助手“既依赖又怀疑”的矛盾心态,Sankel 以一位顶尖语言设计者的视野,为我们抽丝剥茧,还原了一个真实、复杂且充满生命力的 C++ 世界。
这不仅是一场关于技术的探讨,更是一次关于如何在不确定的技术浪潮中寻找确定性的思想碰撞。
以下为对话全文:
吴咏炜:嗨 David,欢迎来全球 C++ 及系统软件技术大会的采访间。请你先向大家打个招呼。
David Sankel:大家好。真的很高兴能来到这里,感觉特别棒。
吴咏炜:首先,我们来探讨一下现代代码与遗留系统的安全性问题。你在本次大会演讲中提到了一个耐人寻味的趋势:大多数内存安全漏洞源于新编写的代码,而不是遗留系统。 你认为这是什么原因造成的?是因为语言固有的复杂性、对现代特性的误用、开发者经验不足,还是工程流程和工具链存在缺口?
David Sankel:这个现象的核心在于“代码硬化”(Code Hardening)的过程,它通常只发生在那些长期承受巨大安全审查压力的旧代码上。
以 Zlib 这个古老的 C 语言库为例,多年来,无数人都在积极地试图攻破它。在这个过程中,绝大多数潜在的漏洞都已经被挖掘并修复了。只要这种对抗性的压力持续存在,代码就会随着时间的推移变得越来越坚固。
漏洞出现在新代码中的原因,实际上仅仅是因为这些代码还没有时间在那种对抗性压力下经过“历练”。这完全是关于漏洞生存周期的问题。如果你看看旧的 Zlib 代码刚出来的时候,它也有成吨的漏洞,那时候的“遗留代码”在当时也是“新代码”。这似乎只是公共领域软件的一种现象,因为人们总是在试图攻击它。
因此,这主要是一个成熟度的问题:代码越成熟,Bug 自然越少。
这种现象积极的一面是,我们不需要回头去处理所有的代码库。如果你拿 Adobe Photoshop 来说,它有 6800 万行代码,我们无法回头去修复所有那些旧代码。但好消息是,我们其实不必像防范新代码那样去焦虑旧代码。我们将防御重点集中在新引入的代码上,这让内存安全问题从一个“不可能完成的任务”变成了一个“可控的工程问题”。
吴咏炜:我们知道,在 C 语言中,由于开发者通常需要直接管理定长数组和原始内存,缓冲区溢出这类问题非常普遍。理论上,C++ 引入了许多现代特性,本应大幅降低此类风险。但现实数据却表明,我们依然面临着大量的内存相关漏洞。为什么在机制更完善的 C++ 中,这类问题依然无法根除?
David Sankel:C++ 确实通过引入高级抽象降低了内存安全漏洞的发生频率,但这并不意味着它从根本上消除了隐患。
现实情况是,工程师仍然很容易写出导致越界访问的代码。过去是对 C 风格数组的越界,而现在的“现代版本”则是对 std::vector 的越界访问——其本质依然是相同的内存安全问题。 再比如使用未初始化的变量,这种风险在 C++ 中也并未消失。
归根结底,C++ 继承了 C 语言的底层内存模型和许多“不安全”的基因。只要这些从 C 语言遗留下来的底层机制仍然被允许使用,或者现代容器的使用方式缺乏强制性的安全约束,内存安全漏洞的温床就依然存在。
吴咏炜: 相比十年前,我们现在拥有了强大得多的动态分析工具。比如 Memory Sanitizer (MSan)、Address Sanitizer (ASan)、Thread Sanitizer (TSan) 以及 Undefined Behavior Sanitizer (UBSan) 等等
David Sankel:你说得完全正确。问题是:这些工具是否在 C++ 生态系统中被普遍使用了?遗憾的是,我认为答案是否定的。
阻碍工具普及的原因可以分为两类。一类是主观因素——比如开发者缺乏认知,或者根本不在乎;但更关键的,是一类非常现实的客观门槛:这些工具的配置成本极高。
要想让这套 Sanitizer 组合在构建系统中完美运行,需要付出巨大的工程代价。这往往要求你在项目启动之初就具备极高的前瞻性,并投入资源去配置基础设施。但在项目早期,你甚至不知道它能不能存活下去,往往无暇顾及这些。
这就导致了一个典型的“成功悖论”:等到你的开源库大获成功、被广泛采用时,它可能一直是在没有 Sanitizer 保护的“裸奔”状态下开发的。突然之间,潜伏的漏洞随着你的库扩散到了整个生态链。
更糟糕的是,即便你现在亡羊补牢加上了防护,下游用户依然可能在使用你的旧版本代码。为什么?因为在 C++ 生 态中,依赖管理和版本升级是一项昂贵的工程活动。用户往往因为升级成本过高而停留在有漏洞的旧版本上,导致问题持续存在。
吴咏炜:但我认为你的论点可能是我们不想用 C++ 写新代码。但其实,我们完全可以在新代码中使用这些工具,而不是在旧代码中,因为旧代码可能有更多的兼容性问题。在新代码中,我们绝对可以使用新工具。
David Sankel:你的论点建立在一个关键假设之上:即只要使用了这些新工具,就能解决所有、或者至少绝大部分的内存安全漏洞。 诚然,它们能大幅缓解问题,但现实数据却给我们泼了一盆冷水。
让我们看看 Google 的数据。在 Android 系统开发中,他们拥有世界顶级的工程师团队,并且在 C++ 开发流程中强制启用了所有的 Sanitizer 和最佳实践。即便武装到了这种程度,他们依然持续发现 C++ 代码中的内存漏洞。
更令人震惊的对比来自于他们引入 Rust 之后的数据:在同样的严苛标准下,C++ 代码产生的内存安全漏洞数量几乎是 Rust 代码的 1000 倍。
这是一个非常“硬”的数据。它揭示了一个残酷的现实:工具只能缓解症状,却无法根治病灶。
如果单靠打开 Sanitizer 就能彻底解决问题,那么 Google 根本不需要大费周章去引入新语言。既然连拥有最强技术实力的 Google 都无法在 C++ 中彻底封堵这些漏洞,这本身就证明了这是一个极其艰深、甚至可能是目前范式下无解的难题。
再举个身边的例子,我团队里的 Sean Parent——他是公认的 C++ 泰斗级人物——依然会踩进内存安全的坑里。有一次他在处理复杂的模板元编程时,面对层层封装的抽象,想要搞清楚一个深埋其中的 auto&& 到底推导出来的是一个右值引用还是一个指向局部变量的悬垂引用,简直难如登天。
吴咏炜:是的,我认为抽象是一个大问题,会让测试 constexpr 函数变得很难……我认为模板元编程还要更难。实际上,我最近也遇到了一个这样的问题,也是在元编程中。我实际上立即发现了问题,因为程序崩掉了。但要弄清楚问题到底在哪真的很难,因为问题隐藏得很深,而且仅在某些特殊场景里才出现。
David Sankel:对,他的情况也是一模一样的。
吴咏炜: 好的,让我们转向下一个关于 C++ 价值主张的问题。如今 Rust 凭借“内存安全”特性迅速崛起,Python 在 AI 时代更是占据主导,也确实吸走了一部分原本依赖 C++ 的用户。但在游戏引擎、系统底层、高性能计算等核心场景,C++ 依旧稳固。在你看来,C++ 最核心、最不可替代的优势是什么?为什么这些优势至今仍难被其他语言取代?
David Sankel:我认为 C++ 拥有一个任何人都夺不走的“利基市场”(Niche),其核心价值主张在于:它允许开发者通过承担“未定义行为”(Undefined Behavior)的风险,来换取绝对极致的性能。
让我用一个最近看到的对比案例来说明。有一段 C++ 代码执行某种整数运算,这其中可能隐含着溢出或除以零的风险。但在编译器的优化下,这段代码被极致精简为一条汇编指令:一个移动加一个加法。
代价是: 如果输入数据错误,程序行为完全不可控(未定义)。
收益是: 如果你能保证数据正确,它就是物理上能达到的最快速度。
当开发者试图在 Rust 中复刻这段代码时,困难出现了。Rust 的安全机制强制要求检查“除以零”和“整数溢出 panic”。为了让 Rust 代码达到和 C++ 一样的指令级效率,开发者不得不使用大量的 unsafe 块、特殊的编译器提示(Hint)和注解。最终,性能确实追平了,但代码量膨胀了四倍,且可读性大打折扣。
这正是 C++ 的生存空间所在——当你愿意接受这种激进的权衡时:
如果你在搞高频交易(HFT),那么程序因为极小概率的错误数据崩溃了,也许可以接受;但如果为了安全检查拖慢了每一笔交易的速度,那就是不可接受的。开发者只要最纯粹、最快的机器码,任何额外的安全检查都被视为累赘;
同样在游戏开发方面,游戏如果出现了一个渲染错误,或者像素偏了一点,甚至偶尔崩溃重启,玩家也许能忍受。但如果为了代码安全导致帧率下降、开发效率变慢(因为要写繁琐的安全注解),那是开发商无法接受的。
除了这种对性能的极致追求,C++ 另一大支柱是历史惯性。
以科学计算领域为例,C++ 的地位并不完全因为它语言设计得多好,而是因为那里已经沉淀了海量的成熟代码。这就像 Fortran 一样——至今像 LAPACK 这样的 Fortran 库仍是数值计算的基石。它们经过了数十年的优化,极其稳定高效,没有任何商业理由去重写它们。
C++ 也是如此。只要这些庞大的遗留代码库(Legacy Codebase)还在运行,只要没人愿意支付天文数字般的重写成本,C++ 就将继续作为这些领域的中流砥柱存在下去。
吴咏炜:这引出了一个关于开发生产力(Productivity)的有趣悖论。刚才你提到,为了在 Rust 中追求极致性能(对齐 C++ 的汇编级优化),代码量可能会膨胀四倍,这意味着生产力大幅下降。但另一方面,业界许多报告又声称 Rust 程序员的生产力显著高于 C++。
这两个截然相反的结论同时存在,是否存在矛盾?也许,这是因为它们应用于不同的领域(domain)?
David Sankel:这绝对是领域决定的,不存在矛盾。关键在于你是否在顺应语言的设计哲学。
如果你试图逆着 Rust 的性子来——比如非要像写 C++ 那样去写充斥着裸指针和极致微操的“不安全代码”——那么是的,你会痛苦万分,生产力会暴跌。
但如果你顺势而为,利用 Rust 擅长的领域——比如进行高层逻辑组装、编写默认安全的业务代码,或者通过安全的接口调用底层高性能库——你会感受到前所未有的生产力飞跃。
让我举一个让我深受震撼的亲身经历:
有一次我在写 Rust 项目,突然觉得如果能嵌入一个 JavaScript 解释器会很棒。在 Rust 里我是怎么做的?我只需要在 Cargo.toml 配置文件里加了一行代码,引入一个现成的 Crate(库)。几秒钟后,我就拥有了一个功能完备的 JS 解释器。
试想一下,如果在 C++ 里做同样的事,会是怎样的噩梦?
我要找一个合适的 C++ JS 引擎库。
我要搞定它复杂的依赖项。
我要想办法让它的构建系统兼容我自己的构建系统。
我还要处理链接、头文件路径等一堆琐事。
在 C++ 里,这是一个天文数字级的工作量;而在 Rust 里,只是“加一行配置”的事。
所以,Rust 所谓的生产力优势,很大程度上并不在于语言语法本身,而在于其现代化的包管理生态系统。Cargo 对于 C++ 开发者来说,简直是降维打击般的体验提升。
吴咏炜:确实,C++ 的痛点不仅仅在于没有统一的包管理器,更深层的原因在于底层的二进制不兼容性。我们有 GCC、Clang、MSVC 等不同的编译器,它们各自有一套不兼容的名称修饰(Name Mangling)规则和调用约定(Calling Conventions)。这导致在 C++ 中分发预编译库(Pre-built Binaries)几乎是不可能的任务,每个人都必须从源码重新编译。
David Sankel:没错,编译器生态的碎片化是一个巨大的阻碍。在 C++ 中,哪怕仅仅是“打包一个库”这样看似简单的动作,都充满了技术挑战。
这里有一个非常深刻的对比。Rust(以及几乎所有现代语言)从诞生之初就吸取了一个教训:工具链必须是语言设计的一等公民。
C++ 只有语言本身(语法和标准库)被 ISO 标准化了。至于如何构建、如何管理依赖、如何生成文档……所有这些工具链层面的东西,标准委员会采取了“放任自流”的态度。
这种差异导致了结果的天壤之别。以文档为例:
在 Rust 生态中,官方直接提供了 rustdoc。因此,整个社区只有一种文档标准,每个人都用同样的方式编写注释,每个人都用同样的工具生成页面。这种同质化(Homogeneity)带来了极大的便利——对于任何一个第三方库,我闭着眼睛都知道去哪里找文档,也知道文档结构长什么样。而在 C++ 中,这完全是混乱的。
吴咏炜:但我并不认为在 C++ 现有的体系下这具有可行性。坦白说,我甚至反感由 ISO 这样的机构去强行标准化工具链或文档工具。在我看来,这根本就是不可能完成的任务。
David Sankel:问题的关键其实不在于组织是否“正式”,而在于产出物的性质。ISO 标准化流程的核心职能非常单一:发布规格说明书(Specification)。仅此而已。
反观 Rust 的组织方式,它完全是另一种范式。Rust 不仅仅发布类似规格的 Rust Reference,它更核心的产出是软件成品。所有这些软件与文档的集合体,才构成了我们认知中的“Rust”。它不仅仅是一纸标准,而是一个完整的产品交付。
这就是两者最根本的区别。ISO 的设立初衷就不是为了开发和维护软件产品。如果我们试图强行通过 ISO 流程来构建一套统一的 C++ 工具链,结果注定会是一场灾难。这不仅违背了 ISO 的基因,在实际操作层面上也完全不可行。
吴咏炜:另一件事是,C++ 的模板特化(Template Specialization),它让 C++ 在某种程度上完美契合了“开闭原则”(Open-Closed Principle):你可以在完全不修改现有通用模板代码的前提下,为特定类型提供扩展实现。
然而,Rust 似乎并没有这种全功能的特化机制,却依然发展得很好。这是否意味着,特化这个优势其实并没有显现出来?还是说 Rust 有其他的替代方案?
David Sankel:这一点非常有意思。当 Sean Parent 和我的团队开始集体学习 Rust 时,他直接切入了最硬核的元编程部分。
几乎是立刻,他就指出了这个痛点:“Rust 没有特化。如果没有特化,你就无法进行真正的泛型编程。” 这对习惯了 C++ 强大元编程能力的专家来说,确实是一个巨大的冲击。
吴咏炜:这就是我不喜欢 Rust 的地方。所以我想听听你的看法。也许那真的没那么重要?或者怎么说?
David Sankel:我必须承认,与 C++ 相比,这确实是 Rust 的一个显著短板。不仅没有特化,Rust 目前也缺乏可变参数模板。这就导致你经常需要用笨办法绕路——比如为了支持不同数量的参数,你得手动把一个函数复制粘贴写很多个版本。
这种感觉让我恍惚间回到了原始的 C++98 时代。但这并非设计者的疏忽,而是深层机制权衡的结果。Rust 引入了严格的借用检查器,并且采用了受检泛型(Checked Generics)模型。
在 C++ 中,即便你定义了 Concept,如果你在模板函数里偷偷用了一个 Concept 没声明的操作,只要实例化时的具体类型支持这个操作,C++ 编译器通常也就睁一只眼闭一只眼放行了。
在 Rust 中(受检泛型),编译器极其严格。它强制要求泛型函数内部只能使用 Trait(对应 C++ 的 Concept)中显式声明的接口。这虽然带来了极佳的接口契约保证,但也使得实现“特化”和“可变参数”在理论上变得异常困难。
目前,Rust 社区虽然有一些关于如何实现这些特性的构想,但尚未落地,这仍是一个未解的难题。
所以归根结底,这就是一种取舍问题,你想要受检泛型带来的类型安全和清晰契约,就不得不暂时忍受特化能力的缺失。你得自己权衡这种交换是否划算。
吴咏炜:那么在你和 Sean 的讨论中,结论是什么?这个特性对 Adobe 或你的项目真的很重要吗?从理论角度来看,要想在一种语言中完全实现 Stepanov风格的泛型编程,你真的需要那种特化。我实际上只是希望我的代码在不修改现有代码的情况下可扩展。所以我想要符合开闭原则。
David Sankel:我认为你在 Rust 里也能得到开闭原则。你可以先定义一个 Trait,声明需要哪些函数, 然后再为 Trait 提供一个通用的默认实现。当一个新类型想要使用这个功能时,它必须显式地为自己实现这个 Trait。
在 C++ 中,泛型函数(如 std::sort)是“即插 即用”的:只要你的类型满足 Concept(或隐式接口)的要求,编译器就会自动选用通用实现。而如果你需要更优的路径,还可以通过模板特化提供定制版本——整个过程无需修改原始泛型代码,也无需显式注册。
但在 Rust 中,这两种能力无法共存。你要么显示地选择加入,然后随心所欲的进行特化,要不你有一个自动实现,但不能特化它。
吴咏炜:好的,所以我们有办法,但是是一种非常不同的方式。
David Sankel:是的,完全正确。C++ 中的 Concept,如果你的语法恰好符合 Concept 的要求,你就支持该 Concept。在 Rust 中,你必须显式地说你支持一个 Trait(这相当于 Concept),并说:“好的,这个特定的类型或这组类型支持这个 Trait,这是它所需的函数的实现。” 所以它是选择加入(opt-in)的语法。
吴咏炜:好的,下一个问题是关于 AI 代码的。随着 AI 编码助手的兴起,许多开源社区正在禁止 AI 生成的贡献。作为标准委员会的一员,你对此有何看法?委员会有没有收到或接受过由 AI 生成的提案或措辞?你有亲自在 C++ 开发中用过过 AI 工具吗?如果有,体验如何?
David Sankel:关于 C++ 标准,确实有过由 AI 编写的提案,而且非常明显,也非常令人讨厌。那样写的提案没有任何进展。当然,这些是我们知道的。也许有人用 AI 写了一个,而且写得太好了以至于我们没有注意到。但我还没有真正看到过这种情况。
我认为开源社区保护自己免受 AI 生成代码贡献的影响是有道理的。因为 AI 写出的一段代码只是完成了一半。另一半是逐行仔细审查,确保它实际上是正确的,并能完成所有需要做的事情。
所以当你有一个开源项目,现在任何人都可以生成做某事的 Pull Request,这意味着该库的维护者必须投入大量的精力,来应对这些贡献者投入的零精力。这里需要某种制衡。也许有人必须证明他们值得信任,并确认一个真正的人类已经花时间检查了这个东西。
我确实有用过 AI 生成代码。以我的经验而言,AI 产生的错误足以让我无法信任它生成的任何东西,除非我亲自检查。 任何将要发布或长期使用的东西,我都必须非常非常小心。
它基本上将我写代码的精力从“编写代码并迭代”转变为“AI 生成代码,我仔细审查”。这感觉不太好。你知道,相比于审查代码,我更喜欢写代码,尤其是当我审查 AI 的代码而它在胡编乱造时,有时候真的很让我恼火。但总的来说,我认为它在大多数情况下节省了时间。所以这可能是值得的。
AI 会变得更好吗?有些人认为它将成为最神奇的东西,你再也不用看代码了。我不相信。我认为对于目前我看到的任何技术和进步,人类都必须保持在循环中(Stay in the loop)。
吴咏炜: 具体来说,你在 C++ 和 Rust 代码上使用 AI 工具的体验如何?
David Sankel:对于 C++:AI 倾向于生成更不安全的代码。
学术研究数据表明,AI 生成的 C++ 代码在客观上比人类编写的代码更差,尤其是在内存安全漏洞方面。
更令人担忧的是一种心理学现象:开发者往往对 AI 生成代码的正确性过度自信,其信心程度甚至超过对自己亲手编写代码的信心。然而现实恰恰相反——AI 生成的代码往往包含更多安全隐患。这是一个相当令人不安的趋势。
对于 Rust,当涉及到内存安全和 AI 生成的代码时,如果 AI 生成的代码不安全,它就不会通过编译。
吴咏炜:对,它是强制性的。这就是区别。
David Sankel:目前 Rust 的语法和特性集比 C++ 小得多、也简单得多,这使得 AI 更容易生成语法正确、看似合理的代码。当然,这不意味着绝对可靠——我确实也见过 Rust AI 产生一些非常疯狂的“幻觉”。
总的来说,我认为无论是 C++ 还是 Rust,现有的代码语料库都已足够庞大,AI 能够进行有效的学习和代码生成。
吴咏炜:我认为至少作为一个辅助工具,AI 是非常有帮助的。顺便说一句,几天前我想让 AI 重构我的一些 C 代码(其实不是 C++),它识别出了一个潜伏了 10 多年的 Bug,因为它从未被触发过。但 AI 注意到我在那里有个拼写错误,把一个变量误写成了另一个。它识别出来了。所以这非常有趣。
David Sankel:是的,我也遇到过这样的时刻,它做了一些事情,你会想,“什么?它怎么……?太神了。”
吴咏炜:最后一个问题。我想谈谈未定义行为(UB)。UB 是大多数内存安全问题的根本原因。目前的标准流程中是否有积极的提案专门旨在减轻未定义行为或增强检测?例如,通过更好的 Sanitizer 或编译器诊断?
David Sankel:是的,一直有稳定的提案流试图解决未定义行为。我相信在 C++26 中,我们首次引入了“错误行为”(Erroneous Behavior)这个概念。这使得一些以前未定义的事情现在有了完整的定义。
还有 Profiles(配置)也被提出过,但这类提案目前还非常不成熟,更像是一些初步构想,缺乏任何实现经验。正因如此,它未能进入 C++26。
让我有点担心的是……最近很多关于未定义行为和解决内存安全漏洞的提案确实是一些“异想天开”的主意。你可以举几个例子说“这是可以被检测到的”,但它们缺乏任何算法,更不用说规范或实现了。我担心这会分散我们的注意力。人们可能会说,“哦,这个问题在未来某个时候会得到解决”,但实际上……那里并没有实质性的东西。
对我来说,目前最扎实、最有趣的努力,来自于 Timur Doumler 等人的一篇论文。他们没有急于提出解决方案,而是做了一项极其重要的基础工作:系统性地编目(Catalog)C++ 标准中每一个已知的 UB 实例,并对它们进行分类。
他们本质上是在用一种科学的方法,为每一个 UB 打上标签,然后问:“对于这一类 UB,我们到底能做些什么?”虽然他们目前还只是在编目阶段,没有提出具体的解决方案,但我认为这才是正确的方向。它让我们第一次有可能从宏观上、系统性地去讨论如何逐步消除 UB,而不是头痛医头、脚痛医脚。
吴咏炜:是的。我想在过去人们认为未定义行为对优化是一件好事。但现在,我认为我们正在朝相反的方向发展。越来越多的人认为未定义行为简直是邪恶的。我们想尽可能地消除它们,对吧?
David Sankel:完全正确。促成这一观念转变的关键因素之一,是 CPU 架构的演进。
让我们以向量(Vector)的索引访问为例。如果你在访问时强制加上边界检。在过去,这可能会带来巨大的性能惩罚,甚至让执行时间变成原来的四倍。而现在,得益于现代超标量架构,配合指令预取和预执行技术,CPU 的流水线能力极强。
这意味着,很多以前昂贵的检查操作,现在被现代硬件的并行能力“消化”了。实际上,你现在基本上可以“免费”(Free)获得这些安全检查,而无需付出明显的性能代价。
吴咏炜:是很多,但不是全部。因为我确实遇到过一个使用 gsl::span 测试的案例。在这个案例中,使用 gsl::span 配合 std::copy 会使复制代码慢 20 倍以上。所以如果我们只做一次性检查,那是可以的。但如果我们不小心做了重复检查,那代价会非常高昂 。
David Sankel:是的。这也是 Rust 生态系统中存在的问题,因为他们想要非常高效的代码,但也想要安全。
如果你深入查看 Rust 标准库的实现,你会发现一种非常巧妙的模式:虽然代码本质上是“安全”的(意味着理论上每次访问都要检查),但开发者会在循环开始前加入一条特定的前置断言,比如“先检查并确认长度小于某个值”。
为什么要这么做?因为编译器(优化器)看到这条前置检查后,就能推断出后续操作是安全的,从而在函数主体的循环中自动消除(Elide)所有那些多余的重复检查。
这就像是开发者与优化器之间的一场“双人舞”:你通过特定的代码写法去“引导”优化器,从而在不牺牲任何安全性的前提下,获得极高的性能。
我认为在 C++ 领域,我们对这种优化技巧讨论得还远远不够,因为我们在内存安全这条路上才刚刚起步。但我相信,同样的原理和机制在 C++ 中也是完全适用的。
吴咏炜:我认为在这种情况下,有一个参考实现真的很有帮助,因为委员会知道他们可以让编译器基于静态分析进行这样的优化,对吧?
David Sankel:对。是的。
吴咏炜: 好的。非常感谢您接受今天的采访。
David Sankel:谢谢。
《近匠》是 CSDN 推出的访谈栏目,其意思即为「走近工匠」,走近深耕于开源、云、AIoT、根技术、数字化转型、前沿技术的工具创造者和技术管理者们,了解他们怎么看待现在的开发工作,分享自己精雕细琢出来的工具有何特点,剖析整个行业发展现状及未来趋势。
为此,基于 AI、开源、系统软件、数字化转型、前沿技术等领域,如果您及团队有报道需求,亦或者如果您有对技术趋势的真知灼见,或是深度的应用实践、场景方案等的新见解,欢迎联系 CSDN 投稿,联系方式:微信(hanbb120,请备注投稿+姓名+公司职位)、邮箱(tumin@csdn.net)。
未来没有前后端,只有 AI Agent 工程师。
这场十倍速的变革已至,你的下一步在哪?
4 月 17-18 日,由 CSDN 与奇点智能研究院联合主办「2026 奇点智能技术大会」将在上海隆重召开,大会聚焦 Agent 系统、世界模型、AI 原生研发等 12 大前沿专题,为你绘制通往未来的认知地图。
成为时代的见证者,更要成为时代的先行者。
奇点智能技术大会上海站,我们不见不散!
热门跟贴