Skip to content
AI Ferryman Alex
Go back

Rust 替代 C,靠的不是重写

Rust 替代 C,靠的不是重写

这一周,两个最保守的代码库一前一后动了手。10 月 27 日,systemd 合并了它的第一个 Rust 程序;就在这几天,Linux 7.4 的合并窗口里,Binder 的 C 驱动被整份删掉,一万一千多行,主线内核里从此只剩 Rust 版。

看到这种新闻,大家爱问一句话:Rust 到底什么时候把 C 替代掉?问的人通常盯着行数算账。内核维护者 Greg Kroah-Hartman 自己给过数字:内核里有三千六百万行 C,Rust 只有十一万三千行。照这个账算,C 再活五百年都没问题。

维护者扛着巨大的螃蟹工具箱爬开机阶梯,只为给系统加一个小组件

可语言不是这么死的。一门语言真正的死法,是新代码不再用它写了。老代码没人动,它就躺在那儿运行、被维护、被打补丁,看上去江山稳固;可每个新组件、每个新驱动、每个新工具,立项那天选的都是另一种语言。存量决定它还能活多久,流量决定它是不是还活着。

你去看这几年几家最保守的项目立的规矩,会发现它们说的是同一条原则:老 C 一行不改,Rust 只准进新代码。内核 2022 年就是这么开的门,先只准新驱动用;去年 12 月,维护者峰会正式宣布实验结束,Rust 是内核的正式语言之一了。

systemd 这次更绝。Rust 只准用在新叶子程序上,就是那种自己独立跑、系统里没有别的东西依赖它的小程序;现有 C 一行不移植,构建不用 Cargo(Rust 自带的包管理和构建工具),不许用外部依赖,连 Rust 标准库都不进成品。第一个 Rust 程序 systemd-keyring-setup 干的活也很小,开机时把证书登记进内核钥匙环。就这么小的一步,10 月 27 日,它合进去了。

再往上,用户每天摸到的那一层也在换。Ubuntu 从 25.10 起把 sudo 换成 Rust 写的 sudo-rs,今年 10 月的 26.10 里,ls、cp、rm 这些最古老的命令已经全部是 Rust 实现,连包管理器的签名验证都换成了 Rust 写的 Sequoia。

维护者为什么愿意签这种规矩?账算在漏洞上。微软和谷歌都估算过,大型 C 和 C++ 代码库里,大约七成严重漏洞是内存错误这一类。谷歌自己的 Android 数据更直观:内存安全漏洞占全部漏洞的比例,2019 年是 76%,到 2025 年降到了 20% 以下,谷歌把这笔账记在新代码改用内存安全语言上。

还有一笔账算在审代码的人身上。Kroah-Hartman 说过,Rust 代码让他审起来轻松得多:类型系统把资源管理那一摊先管住了,他只需要看逻辑对不对。对天天要审成千上万补丁的人来说,这不是口味问题,是人力问题。

Binder 则是下一阶段的样子。谷歌先用 Rust 把这个驱动重写了一份,两个版本并行跑,Rust 版先在 Android 设备上量产;删除时给出的理由是功能已经追平、性能也不输,C 版就在 7.4 里被整份删掉。提交删除的人写了一句话:这一天终于来了。

但 Binder 是个例外,不能当常态看。它背后有谷歌长期投入的钱和人,Android 的进程通信又痛到值得重写。绝大多数 C 子系统不会有这个待遇,它们等不到重写,只会等到一件事:从某一年起,再也没有新功能往里加。老代码就那么放着,一放二十年。

Rust 往核心里走,碰到的硬阻塞也不少。systemd 的核心部分到今天还用不了 Rust,动态库支持有硬伤;发行版那边,Arch 和 openSUSE 前几天刚因为构建开了全功能又没带 Rust 工具链,当场构建失败。

Ubuntu 换 Rust 命令也不是一帆风顺。Canonical 请 Zellic 审的就是 Rust 版的 coreutils,113 个问题里有 44 个是 CVE;cp、mv、rm 还卡过一类竞态问题,就是检查的时候没事、真用的时候文件已经被换掉了,26.04 先留用 GNU 版,拖到 26.10 才换完。

所以这件事的时间尺度,是一代人,不是两年。C 还会运行在每一台机器里很多年,能审 C、能维护 C 的人还会值钱很久。可是值钱的方式会变:从「新东西都找你写」,变成「老系统只有你敢碰」。

你把时间推到二十年后看:新项目立项,默认语言里没有 C;年轻人不学它,除非要去维护老系统;C 的位置,跟今天 COBOL 在银行里的位置差不多:系统离不了它,可除了维护,没人再拿它做新东西。我维护 C 写的基础设施很多年,我怕的从来不是哪天失业,而是有一天发现,我的经验被归档进了「遗留」那一栏。

对还在写 C 的人,我的建议很具体:不用慌着转行,也别赌它不会发生。最该练的,是站在两种语言中间的本事:读得懂 Rust,审得了新组件,知道老 C 的哪一段不能动、哪一段该让新代码绕开它。这种人接下来二十年是最缺的,因为新代码要接入的,全是你们手里的老系统。

判断 C 的死期,别数还剩多少行。看你下一个新组件立项时,默认用什么写。默认值翻过去的那一天,结局其实已经写好了,剩下的只是时间。你手边的新项目,现在默认用什么?

https://www.phoronix.com/news/systemd-Merges-Rust-Programs


在 X 上讨论→

评论都在 X 上——回复、引用和讨论都在那边进行。