文章核心观点 - 在Rust崛起和AI编程兴起的背景下,C++凭借其对底层性能的绝对控制力,在追求极致性能的利基市场依然不可替代,但其在内存安全、工具链生态方面面临严峻挑战 [7][17][20] C++内存安全现状与挑战 - 内存安全漏洞更多出现在新代码中,原因是新代码缺乏“代码硬化”过程,未在对抗性压力下得到充分历练和修复 [10] - 旧代码如Adobe Photoshop的6800万行代码,虽庞大但因其成熟度,安全风险相对可控,将防御重点放在新代码上使内存安全问题变得可控 [11] - C++通过高级抽象降低了内存安全漏洞频率,但未根除隐患,因其继承了C语言不安全的底层内存模型和机制 [12] - 动态分析工具(如ASan、MSan)配置成本极高,且项目早期往往无暇配置,导致成功项目可能在“裸奔”状态下开发并传播漏洞 [13] - 即便强制使用所有Sanitizer和最佳实践,顶级团队(如Google Android)的C++代码中仍持续发现内存漏洞,且数量是Rust代码的约1000倍 [14][15] - 工具只能缓解症状,无法根治病灶,内存安全是C++范式下可能无解的难题,即使顶尖专家也会犯错 [16] C++的核心价值与不可替代性 - C++最核心的优势是允许开发者通过承担“未定义行为”风险,换取物理上可达到的极致性能 [17][18] - 在追求极致性能的场景下,Rust需要大量unsafe块和提示才能达到同等效率,导致代码量膨胀且可读性下降,而C++代码可被极致优化为少量汇编指令 [19][20] - C++另一大支柱是历史惯性,海量成熟遗留代码库(如科学计算领域)的重写成本过高,确保了其持续存在 [20] C++与Rust在生产力及生态上的对比 - Rust的生产力优势高度依赖于其现代化的包管理生态系统(Cargo),在依赖管理上对C++构成“降维打击” [22][27] - 在Rust中嵌入一个JavaScript解释器只需在配置文件中添加一行代码,而在C++中需要处理复杂的依赖、构建系统兼容和链接问题,工作量巨大 [22][23][24][25][26] - C++工具链生态碎片化严重,缺乏统一标准,不同编译器的二进制不兼容性使得分发预编译库几乎不可能 [27][28] - Rust从设计之初就将工具链作为一等公民,提供了统一的标准和工具(如rustdoc),而C++标准委员会仅标准化语言本身,对工具链采取放任态度 [29][31] - ISO标准化流程的核心是发布规格说明书,而非开发和维护软件产品,因此通过ISO统一C++工具链不可行 [31][32] C++与Rust在语言特性上的权衡 - Rust缺乏C++的模板特化和可变参数模板等元编程特性,这限制了其泛型编程能力,有时需要笨拙的绕行方案 [32][33] - 这种缺失是深层机制权衡的结果:Rust严格的借用检查器和受检泛型模型,强制要求泛型函数只能使用Trait中显式声明的接口,带来了类型安全但增加了实现高级特性的难度 [33] - C++的泛型是“即插即用”的,并支持特化以实现开闭原则;而Rust需要类型显式选择加入(opt-in)Trait实现,提供了不同的扩展方式 [34][35][36] AI编程助手的影响与风险 - AI生成的C++代码在客观上比人类编写的代码更差,尤其是在内存安全漏洞方面 [40] - 开发者对AI生成代码的正确性存在过度自信的心理现象,这与代码实际包含更多安全隐患的现实相悖 [40] - 对于Rust,由于其安全机制的强制性,AI生成的不安全代码无法通过编译,这构成了与C++的关键区别 [41][42] - AI工具将开发者的精力从编写代码转变为审查AI生成的、可能包含错误的代码,虽然可能节省时间,但人类仍需保持在循环中 [37][38] - 开源社区禁止AI生成贡献是合理的,因为维护者需要投入大量精力审查贡献者投入零精力生成的代码 [37] 对未定义行为(UB)的应对与优化趋势 - 观念正在转变,从未定义行为有利于优化,转向尽可能消除未定义行为 [46] - 现代CPU架构的演进(如超标量、指令预取)使得许多安全检查的性能代价变得极低,甚至“免费” [47] - Rust标准库采用一种模式:通过循环前的前置断言引导编译器优化,从而在循环体内消除重复的安全检查,实现安全与高性能的兼得 [48] - 同样的优化原理在C++中完全适用,但相关讨论和实践尚在起步阶段 [49] - 目前针对UB最扎实的努力是系统性地编目和分类标准中的每一个UB实例,为系统性解决方案奠定基础 [45]
“AI 写的 C++ 代码,客观上比人类更烂”,吴咏炜对话 Adobe 首席科学家 David Sankel|近匠
AI科技大本营·2026-02-16 15:43