一切皆关乎内存安全
看到文章标题,很多人会联想到“Rust 开发者”,因为他们热衷于追求内存安全。部分原因可能是“语言之争”心态,但希望多数人是真心想让软件更安全。不过,这篇文章并非关于 Rust 开发者。
过去的内存安全状况
此前,非垃圾回收(GC)的系统编程语言如 C、C++、Zig 和 Rust 中,内存安全相关讨论基础较简单。Rust 禁止编译可能引发内存安全问题的程序,设有 `unsafe` 机制;C 等语言将确保内存安全的任务交给程序员。不同语言提供的帮助程度有别,C++ 有资源获取即初始化(RAII)和智能指针,Zig 有 `defer` 机制,但大多无法阻止违反内存访问规则的行为。
Fil - C 带来新变化
如今,有了让 C、C++ 及未来可能的 Zig 代码实现内存安全的新方法:Fil - C。用 Fil - C 编译的 C 和 C++ 代码,出现无效内存访问时会崩溃,它通过结合 GC 和 InvisiCaps 实现这一点。Zig 的作者宣布了受 Fil - C 启发的新编译模式。Fil - C 是个有趣的项目,希望有流行的 C 和 C++ 项目能提供 Fil - C 编译版本。
两种语言的争议
理想情况下,关心内存安全的 Rust 与 C/C++/Zig 程序员都会为有更多减少内存安全漏洞的方法而高兴。但近期很多对 Rust 的批评不真诚,Fil - C 作者不喜欢 Rust,称其内存不安全,Zig 作者 Andrew Kelley 似乎也持类似立场。在相关讨论中,常出现“如果 Rust 开发者真的关心内存安全,就会推广 Fil - C 并放弃 Rust”的说法。这类观点无视现实,像狂热和类似邪教的行为。
Fil - C 的权衡之处
若 Fil - C 是无代价的替代方案,或许会部分认同上述观点,但它存在权衡:与非 Fil - C 编译的程序有应用二进制接口(ABI)不兼容问题,某些情况下可能慢几倍,还引入了 GC。对一些程序而言,这些并非致命问题,但很多流行项目中,GC 和 ABI 不兼容是大问题,它们不会采用 Fil - C 技术,无法使用 Fil - C 的程序往往适合用 Rust。
Rust 的安全性
有人认为 Rust 不安全,因为有 `unsafe`。但目前关于 Rust 在实践中安全性的数据不多,据了解,Rust 软件中可利用的内存安全漏洞不多。如安卓系统中有超过 500 万行的 Rust 代码,只发现一个潜在内存安全漏洞,估计 Rust 的漏洞密度为每百万行代码(MLOC)0.2 个漏洞,而 C 和 C++ 每 MLOC 约有 1000 个内存安全漏洞,Rust 代码漏洞密度低几个数量级。
技术选择与建议
若能选择,一种技术能在 100% 的程序中预防 99.9% 的问题,另一种能在 90% 的程序中预防 100% 的问题,虽不清楚实际数据,但不必二选一。希望能用 C/C++/Zig 编写、能接受权衡的项目,提供 Fil - C 编译的二进制文件;无法接受的软件,可用能完全或大部分消除内存安全问题风险的语言编写。即便能用 Go 或 Fil - C 这样的 GC 语言,使用 Rust 也没问题。内存安全绝对主义者的观点令人费解,不狂热解决问题的人会考虑权衡因素。最后,如果有人连 Rust 每百万行代码 0.2 个漏洞都无法接受,希望他们更严厉地批评随意编译 C/C++ 和非 Fil 版 Zig 代码的人。