关于 Rust、C 和 C++ 的讨论,互联网上已经太多了。常见的说法有几种:

  • Rust 会取代 C / C++;
  • C / C++ 永远不会死;
  • Rust 只是社区炒作;
  • C++ 太复杂,迟早被淘汰;
  • Rust 学习曲线太高,不可能普及;
  • C 才是真正的系统语言;
  • C++ 的存量生态不可撼动。

这些说法里面,有些对,有些错,有些只是情绪表达。但如果真正站在软件工业、系统工程、安全工程、语言生态和个人职业发展的角度看,这件事远比一句 “取代” 或者 “不会取代” 复杂。我觉得更准确的问题不是:

Rust 会不会让 C 和 C++ 消失?

因为这个问题太粗糙。脑子清醒的人都知道,C 和 C++ 不可能消失。它们背后有几十年的存量代码、操作系统、数据库、浏览器、游戏引擎、嵌入式、音视频、图形、科学计算、工业软件、金融系统、芯片 SDK、驱动和基础库。真正值得问的是:

未来新项目立项时,C 和 C++ 还会不会是默认首选?
Rust 能不能让很多原本会用 C / C++ 的新系统项目转向?
C / C++ 哪些领域会被分流?
哪些地方即使抛开历史原因,也很难被分流?
作为一个 C++ 开发者,面对这种变化应该学什么?

这篇文章就是围绕这个问题展开的。

Rust 的目标不是让 C / C++ 消失

很多关于 Rust 的争论,一开始就歪了。有人说:

Rust 不可能取代 C / C++,因为 Linux、Windows、OpenSSL、ffmpeg、LLVM、Unreal、Chrome、数据库、嵌入式系统都不会重写。

这当然对。但 Rust 社区里更现实、更有战略意义的目标并不是 “把所有 C / C++ 存量系统重写一遍”(虽然有些人正在这么做,但是很欣慰的是受到了 Rust 社区内外的一致抵触)。真正的目标更像是:

遏制 C 和 C++ 产生新的项目,让未来越来越多系统工程的新项目不再默认首选 C / C++。

这件事就现实多了。过去很多项目选择语言时,默认心智大概是这样的:

  • 要性能?C++。
  • 要底层控制?C。
  • 要写操作系统组件?C / C++。
  • 要写驱动?C。
  • 要写数据库、存储、网络栈?C / C++。
  • 不想要 GC?C++。
  • 要和硬件贴近?C。
  • 要写高性能工具?C++。

Rust 想改变的就是这个默认链条。Rust 并不是说:

C / C++ 明天就消失。

而是在说:

如果今天从零开始写一个新的系统组件,尤其是安全敏感、网络暴露、处理不可信输入的组件,那么为什么还要默认选 C / C++?

一旦行业心智从:

“系统项目默认 C / C++,除非有理由不用。”

变成:

“系统项目先考虑 Rust,除非有理由必须用 C / C++。”

那么 Rust 就已经取得了巨大的历史胜利。

所以这场竞争不是 “消灭存量”,而是 “争夺新增”。

成熟资产和新项目不是一回事

安全领域是理解这件事最好的例子。如果有人说:

Rust 更安全,所以 OpenSSL 应该被 rustls 替代。

这个说法太天真。现实中的安全工程不是只看语言。假如我是一个项目 CEO,或者一个大型基础设施项目负责人,我要选择 TLS 库,我不会只问:

这个库是不是 Rust 写的?

我会问:

  • 它被多少真实攻击打过?
  • 它经过多少年审计?
  • 它支持多少奇怪平台?
  • 它和多少客户端、服务器、证书系统兼容?
  • 它有没有 FIPS 或其他合规认证路径?
  • 它有没有成熟的漏洞响应机制?
  • 它有没有足够多的安全专家长期盯着?
  • 它在真实互联网环境里跑了多少年?
  • 它被银行、云厂商、浏览器、操作系统、大型企业使用过吗?
  • 出问题时谁来负责?

OpenSSL 虽然是 C 写的,也出过很多严重漏洞,但它的历史信用非常深。它被攻击过,被审计过,被修过,被大量系统部署过,被无数奇怪输入折磨过。它的代码里当然有历史包袱,但它也积累了巨大的实战经验。而一个年轻的 Rust TLS 库,即便理念先进、内存安全更好,也不自动意味着整体安全风险更低。因为 TLS 库的安全不只是内存安全。它还包括:

  • 协议状态机正确性;
  • 证书链验证;
  • X.509 解析;
  • 密码套件选择;
  • downgrade attack 防护;
  • replay attack 防护;
  • random number 使用;
  • constant-time;
  • timing side-channel;
  • cache side-channel;
  • padding oracle;
  • API 是否容易误用;
  • 平台兼容性;
  • 硬件加速;
  • 合规认证;
  • 长期审计;
  • 供应链安全;
  • 真实世界互操作性。

Rust 在语言层面主要解决的是内存安全。它不能自动保证 TLS 状态机没有逻辑漏洞,也不能自动保证密码算法 constant-time,更不能自动给一个库十几二十年的审计信用。所以,如果问题是:

我现在要不要把成熟稳定的 OpenSSL 替换成一个年轻 Rust 库?

答案通常不会因为 “Rust 更安全” 就变成 “当然要”。但如果问题变成:

今天从零开始写一个新的安全组件,要不要用 C / C++?

那答案就完全不同了。比如今天要新写:

  • 证书解析器;
  • 图片解析器;
  • 字体解析器;
  • 压缩格式解析器;
  • 网络协议解析器;
  • sandbox 边界组件;
  • WebAssembly runtime;
  • 身份认证网关;
  • 密钥管理组件;
  • 安全扫描器;
  • 边界代理;
  • VPN / 代理组件;
  • 新的安全网关;
  • 新的协议栈。

这时候如果还选 C / C++,安全团队很可能会问:

为什么我们要主动选择一门更容易产生 use-after-free、buffer overflow、double free、越界访问和数据竞争的语言?

这就很难解释。因此更准确的判断是:

OpenSSL 不一定会被 rustls 打败。
但未来很少有人愿意再用 C 写一个新的 OpenSSL。

这句话才是 Rust 对 C/C++ 安全领域真正的威胁。Rust 不一定消灭成熟 C/C++ 安全资产,但它会阻止新的 C/C++ 安全资产继续诞生。

Rust 的内存安全已经足够重要

这里也要避免一个 Rust 支持者常见的过度宣传:

Rust 安全,所以 Rust 在安全领域全面优于 C / C++。

这个说法不严谨。Rust 在语言层面最主要解决的是内存安全和一部分并发安全问题,比如:

  • use-after-free;
  • double free;
  • buffer overflow;
  • out-of-bounds read/write;
  • dangling pointer;
  • iterator invalidation;
  • 一部分未初始化内存;
  • 数据竞争;
  • 资源生命周期混乱。

这些问题确实是 C / C++ 安全漏洞的大头。大量浏览器、操作系统、网络服务中的高危漏洞都和内存安全有关。所以 Rust 的价值非常实在。但 Rust 不会自动解决:

  • 密码算法是否正确;
  • 协议设计是否正确;
  • 认证流程是否正确;
  • 证书验证是否正确;
  • 权限模型是否正确;
  • 状态机是否正确;
  • 是否 constant-time;
  • 是否有侧信道;
  • 是否有供应链攻击;
  • 是否有依赖投毒;
  • API 是否容易误用;
  • 系统配置是否安全;
  • 运维是否正确;
  • 合规认证是否满足;
  • 安全审计是否充分。

所以说:

Rust 只解决内存安全。

这个说法大体成立。

但也要补充一点:Rust 虽然不自动解决非内存安全问题,但它的类型系统确实能帮助减少一部分安全工程错误。比如 Rust 的:

  • Option
  • Result
  • enum;
  • pattern matching;
  • ownership;
  • borrowing;
  • move semantics;
  • trait;
  • 类型状态建模。

可以帮助你表达:

  • 已验证证书和未验证证书不是同一种东西;
  • 握手前状态和握手后状态不能混用;
  • 明文密钥不能随意复制;
  • 某个资源不能在释放后继续使用;
  • 某个对象不能跨线程共享;
  • 某个错误不能被静默忽略;
  • 某些权限 token 必须线性消费。

这些不是密码学正确性本身,但它们是安全工程的一部分。所以更准确的说法是:

Rust 不会自动让安全组件正确,但 Rust 能让很多危险错误无法通过编译,并且能帮助开发者更明确地表达安全状态和资源边界。

不过在 OpenSSL、BoringSSL、LibreSSL、libsodium 这类成熟项目面前,Rust 年轻库的优势并不一定压倒经典 C / C++ 库的历史信用。

因此安全领域未来更可能是:

  • 成熟 C / C++ 安全基础设施继续存在;
  • 新增安全边界组件优先 Rust/Go/Java/C# 等内存安全语言;
  • 关键密码库需要十年级别部署、审计、攻击和修复,才能建立真正信用;
  • Rust 安全生态会成长,但不会因为语言先进就自动获得信任。

为什么很多语言挑战 C / C++ 失败?

C/C++ 很难被挑战,不是因为它们语法好,也不是因为它们没有缺点。恰恰相反,C/C++ 的缺点太明显了:

  • 内存安全差;
  • UB 多;
  • 构建系统复杂;
  • 包管理长期混乱;
  • C++ 语言复杂度爆炸;
  • 模板错误难读;
  • ABI 问题复杂;
  • 大型工程维护痛苦;
  • 安全漏洞成本高。

但 C / C++ 的护城河也非常强。它们拥有一个非常罕见的组合:

  • 性能接近硬件上限;
  • 无 GC;
  • 资源控制可预测;
  • 可以操作内存布局;
  • 可以贴近 ABI;
  • 可以写操作系统、驱动、数据库、浏览器、游戏引擎;
  • 可以裸机;
  • 可以嵌入式;
  • 可以和硬件厂商工具链对接;
  • C ABI 是事实上的跨语言接口标准;
  • 平台支持几乎无处不在;
  • 生态和存量巨大;
  • 调试器、profiler、sanitizer、编译器工具链成熟;
  • 工程师经验积累深。

所以挑战 C / C++ 的语言,不能只说:

我更安全。

也不能只说:

我更好写。

它必须回答:

  • 有没有 GC?
  • 能不能裸机?
  • 能不能写内核?
  • 能不能控制内存布局?
  • 能不能和 C ABI 交互?
  • 性能是不是接近 C / C++?
  • 资源释放是不是可预测?
  • 能不能渐进迁移?
  • 工具链能不能支撑大型工程?
  • 大公司敢不敢用?

历史上很多语言都没有同时回答好这些问题。

Java 和 C#

Java 和 C# 都非常成功。它们抢走了大量原本可能由 C++ 编写的企业应用、服务器应用、桌面应用、平台应用。但它们没有真正替代 C / C++ 的系统编程位置。原因很简单:

  • 有 GC;
  • 有运行时;
  • 不适合裸机;
  • 不适合内核;
  • 不适合驱动;
  • 不适合硬实时;
  • 内存布局控制不够直接;
  • 与 ABI 和硬件之间隔了一层;
  • 延迟和资源释放不完全由程序员直接控制。

这不是说 Java / C# 不好,而是它们赢的是应用层和企业层,不是系统底层。它们对 C++ 是部分成功,而不是全面替代。

Go

Go 也很成功,尤其是在云原生、网络服务、平台工程、基础设施工具里。Docker、Kubernetes、Prometheus、etcd、Terraform 等生态都让 Go 拥有巨大影响力。Go 的优势是:

  • 简单;
  • 编译快;
  • 部署方便;
  • goroutine 好用;
  • 标准库强;
  • 工程一致性好;
  • 招聘和团队协作友好。

Go 确实抢走了很多过去可能会用 C++ 写的服务端基础设施项目。但 Go 也有边界:

  • 有 GC;
  • 底层控制力不如 C/C++/Rust;
  • 类型系统相对保守;
  • 不适合内核、驱动、裸机;
  • 不适合极端低延迟;
  • 不适合很多需要精细内存布局的项目;
  • 性能强,但不是 C / C++ 那种极限模型。

所以 Go 更像是:

更简单的云基础设施语言。

而不是:

更安全的 C++。

D

D 语言曾经非常像 “更好的 C++”。

它有:

  • 系统编程能力;
  • 高性能;
  • 现代语法;
  • 模板;
  • 可选 GC;
  • C 互操作。

但 D 没有成为主流。

原因包括:

  • 生态没有起来;
  • 标准库和编译器路线分裂;
  • 社区规模有限;
  • 企业背书不足;
  • 没有形成不可替代的核心叙事;
  • C11 之后 C 自己吸收了一部分现代特性;
  • 没有像 Rust 那样抓住 “内存安全” 这个政策级、组织级驱动力。

D 是一个典型例子:技术上很有野心,但没有形成产业势能。

Ada/SPARK

Ada 和 SPARK 在高可靠领域非常强。它们适合:

  • 航空航天;
  • 军工;
  • 高可靠系统;
  • 需要形式化验证的项目。

但它们没有成为通用系统编程主流。原因包括:

  • 社区小;
  • 工具链和生态相对封闭;
  • 普通互联网公司采用少;
  • 学习和行业门槛高;
  • 开源世界存在感有限;
  • 语言形象偏专用、高可靠、政府 / 军工。

Ada 是局部成功,但不是广义替代。

Swift

Swift 很现代,也有不错性能。但它主要成功在 Apple 生态。它的问题是:

  • 心智上绑定 Apple;
  • Linux/服务器/嵌入式/内核生态弱;
  • 系统编程社区心智不如 Rust;
  • 没有形成 “C / C++ 安全替代者” 的强叙事。

Swift 是成功语言,但不是广义 C / C++ 挑战者。

Zig

Zig 是很值得关注的语言。它的优势包括:

  • 简洁;
  • 无 GC;
  • 显式控制;
  • C 互操作优秀;
  • 交叉编译体验好;
  • 构建系统野心大;
  • 学习曲线比 Rust 平缓;
  • 很适合底层、小系统、工具链场景。

但 Zig 和 Rust 最大不同是:

Zig 更像更好的 C,Rust 更像内存安全的系统语言。

Zig 没有 Rust 那种强所有权 / 借用模型,也没有把内存安全作为最大产业叙事。所以 Zig 可能会挑战 C 的一部分生态位,尤其是想要更现代、更干净、更好工具链的 C 场景。但它不一定能替代 Rust 在 “内存安全系统工程” 里的定位。

Rust 为什么特殊?

Rust 之所以被认为是 C / C++ 的强力挑战者,不是因为它语法时髦,也不是因为它社区热闹,而是因为它第一次比较完整地回答了系统程序员最在意的几个问题。

Rust 没有 GC

这是关键。

很多语言挑战 C / C++,第一关就死在 GC 上。

不是说 GC 不好。GC 对大量应用开发非常好。

但对 C / C++ 的核心地盘来说,GC 经常是硬伤:

  • 内核不想要;
  • 驱动不想要;
  • bootloader 不想要;
  • 嵌入式不一定能承受;
  • 硬实时不想要;
  • 低延迟交易系统不想要;
  • 游戏引擎关键路径不想要;
  • 数据库存储引擎不一定想要;
  • 密码库和基础库不想依赖大运行时;
  • 系统 runtime 自己不能依赖另一个复杂 runtime。

Rust 的特殊之处在于:

它不靠 GC 管内存,而是在编译期尽量证明内存使用合法。

这使它能进入 C / C++ 真正核心的领域。

Rust 保留了系统编程能力

Rust 可以做很多传统 C / C++ 做的事情:

  • 控制内存分配;
  • 栈 / 堆区分;
  • 自定义 allocator;
  • 零成本抽象;
  • 指针操作;
  • SIMD;
  • FFI;
  • no_std;
  • 裸机开发;
  • 嵌入式;
  • 操作系统组件;
  • 驱动;
  • WebAssembly runtime;
  • 数据库;
  • 编译器;
  • 网络栈。

当然,很多底层操作需要 unsafe。但这正是 Rust 的现实主义:

底层危险不可避免,但可以把危险圈起来,让 safe 部分成为默认。

C / C++ 是整个语言空间都可能 unsafe,而 Rust 是默认 safe,必要时进入 unsafe island。这对大型团队和安全审计意义很大。

Rust 攻击的是结构性问题

C / C++ 的内存安全问题不是靠 “高手小心点” 就能彻底解决的,几十年来,我们已经有了:

  • 静态分析;
  • code review;
  • sanitizers;
  • fuzzing;
  • RAII;
  • smart pointers;
  • Core Guidelines;
  • modern C++;
  • 编码规范;
  • 安全子集;
  • lifetime analysis 尝试。

这些都很有用,但没有从根上改变 C/C++ 的语言模型。C/C++ 仍然允许你:

  • 使用悬垂指针;
  • 越界访问;
  • 重复释放;
  • 错误别名;
  • 触发 UB;
  • 在并发中产生数据竞争。

Rust 的吸引力在于:

不是要求程序员更小心,而是让大量错误无法通过编译。

这对企业、安全团队、政府和大公司非常有吸引力。尤其现在 memory-safe languages 已经成为政策和产业话题。美国、欧洲、各大科技公司都越来越重视内存安全语言。这是过去 D、Ada、Go 等挑战者没有同时获得的产业风向。

Rust 可以渐进进入 C / C++ 系统

Rust 不需要你一次性重写几百万行 C++。它可以走现实路线:

  • 老核心继续 C / C++;
  • 新模块用 Rust;
  • 新解析器用 Rust;
  • 新安全边界组件用 Rust;
  • 新 CLI 工具用 Rust;
  • 新存储组件用 Rust;
  • 新网络代理用 Rust;
  • 通过 FFI 和原系统连接;
  • 慢慢扩大 Rust 代码比例。

这就是 Rust 最危险的地方。它不需要马上替换整个系统。它只需要在每一次新增模块时赢一点点。长期看,新增项目份额就会变化。

Cargo 和工具链体验是巨大优势

C / C++ 的工程体验长期很痛苦:

  • Makefile;
  • CMake;
  • Autotools;
  • Bazel;
  • vcpkg;
  • Conan;
  • 系统包管理器;
  • 平台 SDK;
  • 编译器差异;
  • 链接问题;
  • ABI 问题;
  • 依赖版本问题;
  • 跨平台构建问题。

C++ 程序员往往已经习惯痛苦了,但新团队、新项目、新人并不一定愿意继续承受。Rust 的 Cargo、crates.io、rustup、rustfmt、clippy、测试、文档生成这一整套工具链,对于新项目吸引力很强。Rust 不只是语言安全,它的现代工程体验也在分流 C++。

Rust 会不会被 “程咬金” 截胡?

可能。Rust 不是终点,也不是完美语言。它有很多现实问题:

  • 学习曲线陡;
  • borrow checker 难;
  • 生命周期让新人崩溃;
  • 编译速度慢;
  • async 复杂;
  • trait / generic 系统有时过于绕;
  • 宏系统强但复杂;
  • unsafe 仍然不可避免;
  • C++ 互操作不够自然;
  • ABI 稳定性不足;
  • 某些领域生态薄弱;
  • crate 依赖树和供应链治理有风险。

所以未来出现一个新语言,说:

我有 Rust 的无 GC、性能和内存安全,但语法更简单、编译更快、异步更自然、C++ 互操作更好。

这是完全可能的。

潜在 “程咬金” 有几类。

Zig

Zig 可能会在一些 C 的生态位上成功。它简洁、直接、无 GC、C 互操作强、交叉编译体验好。但 Zig 不以强内存安全作为核心卖点。所以它更可能成为:

更现代、更舒服、更工程化的 C。

而不是全面取代 Rust 的安全系统语言。

Carbon / Cpp2

Carbon 和 Cpp2 这类东西,本质上想给 C++ 找一条现代化迁移路线。如果它们能做到:

  • 与 C++ 无缝互操作;
  • 迁移成本低;
  • 性能保持;
  • 工具链成熟;
  • 大厂支持;
  • 安全性显著提升;
  • 保留 C++ 生态资产;

那它们会对 Rust 形成很大威胁。因为很多公司最大的问题不是 “Rust 好不好”,而是:

我已经有 500 万行 C++,怎么办?

如果有一种语言能作为 C++ 的自然继承者,并且迁移成本远低于 Rust,那它当然有吸引力。但目前看,这条路还非常不确定。C++ 的历史包袱太重。要在保留兼容性的同时显著改善内存安全,极其困难。

Mojo

Mojo 更偏 AI、高性能计算、Python 生态加速。它如果成功,可能会影响:

  • AI 基础设施;
  • 数值计算;
  • GPU kernel;
  • Python 性能扩展;
  • 高性能计算。

Mojo 未必正面替代 Rust,而可能直接吃掉一些 Rust 本来可能进入的 AI / HPC 新领域。

安全 C++

C++ 社区不是什么都不做。未来可能会有:

  • lifetime profile;
  • safety profiles;
  • 静态分析强化;
  • sanitizers 常态化;
  • C++ Core Guidelines;
  • 编译器强制安全模式;
  • 受限 C++ 子集;
  • Herb Sutter 的 Cppfront / Cpp2;
  • Google、Microsoft 等推动安全 C++。

如果 C++ 能在不破坏生态的情况下显著降低内存安全风险,Rust 的上升速度会受影响。但这很难。因为 C++ 最大的问题是兼容性。它不能轻易禁止大量历史写法。它的自由和混乱是同一个硬币的两面。

但 Rust 不会被 “突然” 截胡

即使未来出现更好的语言,Rust 也不会突然消失。语言生态变化很慢。一个新语言要经历:

  1. 爱好者使用;
  2. 小工具验证;
  3. 中型项目采用;
  4. 大公司试点;
  5. 工具链成熟;
  6. 生态形成;
  7. 招聘市场出现;
  8. 关键基础设施采用;
  9. 安全审计和长期部署积累;
  10. 形成产业信任。

这个周期通常是 5 到 15 年。Rust 现在已经不是玩具语言。它已经进入:

  • Linux kernel;
  • Android;
  • Windows 的部分安全讨论和组件;
  • AWS;
  • Cloudflare;
  • Google;
  • Microsoft;
  • Mozilla;
  • WebAssembly 生态;
  • Firecracker;
  • Wasmtime;
  • TiKV;
  • Vector;
  • Deno;
  • Ruff;
  • uv;
  • SWC;
  • ripgrep;
  • fd;
  • bat;
  • starship;
  • Zed 等工具和项目。

Rust 已经占住了一个很强的心智:

Rust = memory safety + no GC + systems programming + performance + C/C++ alternative。

后来者要赢,不能只是更好一点,必须好很多,并且还要花十年级别积累信任。所以更可能的未来不是 Rust 被某个语言一击打倒,而是:

Rust 还没完全吃掉 C / C++,就被 Zig、Carbon、Mojo、安全 C++、Go 等从不同方向分流。

不是一门语言统一天下,而是多语言重新划分生态位。

C / C++ 被分流是必然

C / C++ 的一部分市场,本来就是历史偶然和路径依赖。很多项目过去用 C++,不是因为 C++ 最适合,而是因为:

  • 当时没有 Rust;
  • Go 还没成熟;
  • Java / C# 有 GC;
  • Python 太慢;
  • 需要性能;
  • 需要系统接口;
  • 团队习惯;
  • 行业默认。

但很多项目其实不需要 C++ 那种极端自由。比如:

  • 普通业务系统;
  • 普通网络服务;
  • 大量工具;
  • 安全扫描器;
  • 数据处理管道;
  • 日志系统;
  • 包管理器;
  • 新的 CLI;
  • 新的代理服务;
  • 普通后端;
  • 部分中间件;
  • 部分系统组件。

这些项目需要的是:

  • 足够性能;
  • 可维护性;
  • 安全性;
  • 好部署;
  • 好招聘;
  • 好工具链;
  • 少踩坑。

它们并不需要:

  • 全局裸指针自由;
  • 到处 reinterpret_cast;
  • 手动释放;
  • Undefined Behavior;
  • 复杂模板怪物;
  • 任意内存别名;
  • 任意对象生命周期 hack。

过去很多项目是 “用大炮打蚊子”:只是想要性能,却被迫承受 C++ 的复杂性和内存风险。所以这些领域被 Rust、Go、Java、C#、Swift、Python、TypeScript 分流是必然的。C++ 会失去很多本来不该属于它的新增项目。这不是坏事。反而说明语言生态变成熟了。

C 和 C++ 仍有很难被分流的东西

虽然 C / C++ 会被分流,但不能说它们只靠历史活着。即使不谈存量生态,它们也有语言模型层面的硬优势。而且 C 和 C++ 的硬优势不一样。

C :极薄底层边界能力

C 最强的地方,不是它安全,不是它现代,而是它足够薄。C 接近一种 “可移植汇编”。它适合表达:

  • 函数;
  • 指针;
  • 数值;
  • struct;
  • 内存布局;
  • 调用约定;
  • 系统边界;
  • 硬件寄存器;
  • ABI。

C 的最硬优势之一是 C ABI。几乎所有语言都能调用 C:

  • Rust 调 C;
  • Python 调 C;
  • Java 通过 JNI 调 C;
  • C# P / Invoke 调 C;
  • Go 调 C;
  • Swift 调 C;
  • Zig 调 C;
  • Lua/Ruby/Node 原生扩展也大量围绕 C ABI。

C ABI 是事实上的跨语言最低公分母。相比之下:

  • C++ ABI 复杂;
  • Rust ABI 不稳定;
  • Go/Java/C# 有运行时模型;
  • Swift ABI 有平台语境;
  • Python 不是系统 ABI。

所以未来即使一个库内部用 Rust 写,对外接口很可能仍然是 C ABI。比如:

1
int library_do_something(const char* input, size_t len);

C 可能不再是实现语言首选,但会长期是接口语言、边界语言、胶水语言。

C 适合最小运行时和裸机

有些地方你什么都没有:

  • 没有堆;
  • 没有线程;
  • 没有文件系统;
  • 没有动态链接器;
  • 没有异常;
  • 没有标准库;
  • 没有完整 runtime;
  • 甚至还在启动阶段。

比如:

  • bootloader;
  • 内核早期初始化;
  • 裸机固件;
  • 芯片 bring-up;
  • runtime stub;
  • freestanding 环境;
  • 极小 MCU 程序;
  • 硬件测试程序。

C 在这里非常自然。Rust 也有 no_std,Zig 也能做,但 C 的语言模型天生就很薄。你基本知道一段 C 会生成什么样的机器码,需要什么运行时支持。这在极底层仍然很有价值。

C 适合硬件寄存器

硬件手册里经常直接给 C 宏或 C 结构体。

比如:

1
2
3
#define UART_BASE 0x40001000
#define UART_DR (*(volatile uint32_t *)(UART_BASE + 0x00))
#define UART_SR (*(volatile uint32_t *)(UART_BASE + 0x04))

这种东西用 C 写就是自然。C 当然有坑:

  • padding;
  • alignment;
  • endianness;
  • bit field 可移植性;
  • strict aliasing;
  • volatile 语义复杂。

但它和硬件文档、寄存器、协议头、DMA buffer、boot protocol 的心智距离很近。因此 C 很难从这些底层边界彻底退出。

C++:复杂高性能工程表达力

C++ 的硬优势和 C 不一样。C 是薄、简单、贴近 ABI。C++ 是复杂、强大、能承载大型高性能抽象系统。它的核心能力是:

零成本抽象 + 极端自由 + 能容纳现实工程的混乱。

零成本抽象仍然非常强

C++ 可以写很高级的抽象,同时努力不为没用到的东西付运行时成本。它有:

  • templates;
  • constexpr;
  • concepts;
  • RAII;
  • move semantics;
  • inline;
  • operator overloading;
  • expression templates;
  • CRTP;
  • policy-based design;
  • allocator-aware containers;
  • ranges;
  • metaprogramming。

这些东西复杂,但高手可以用它们构建非常强的高性能库。比如 Eigen 这种线性代数库,就大量依赖 expression templates,把数学表达式压到编译期优化。游戏引擎、图形库、数值库、HPC 库、数据库执行引擎,也经常需要这种 “高层抽象 + 低层性能” 的混合能力。Rust 也有零成本抽象,而且内存安全更强。但 C++ 在某些领域的表达自由度和历史积累非常深。尤其是当你需要把高级抽象、手写内存管理、平台特化和老接口全部揉在一起时,C++ 仍然很顺手。

C++ 的 RAII 表达非常成熟

C++ 的 RAII 是极其强大的思想。资源不只是内存,还包括:

  • 文件句柄;
  • socket;
  • mutex;
  • GPU resource;
  • texture;
  • command buffer;
  • transaction;
  • lock guard;
  • mmap;
  • database handle;
  • temporary arena;
  • scope rollback。

C++ 用构造函数和析构函数表达资源生命周期,非常自然。Rust 的 ownership 和 Drop 在这方面也很强,甚至更安全。但 C++ 的 RAII 与对象模型结合得非常深,很多工程师已经形成了很成熟的资源管理习惯。在一些复杂系统中,C++ 的灵活性仍然非常高。

C++ 特别适合共享可变状态

很多现代安全语言都希望你说清楚:

  • 谁拥有对象;
  • 谁借用对象;
  • 谁能修改对象;
  • 生命周期多长;
  • 是否跨线程;
  • 是否共享;
  • 是否可变。

这是好事。但很多真实系统就是非常不规则:

  • 游戏场景图;
  • GUI object tree;
  • 编译器 IR;
  • 数据库执行计划;
  • ECS;
  • observer list;
  • callback registry;
  • plugin system;
  • cache;
  • 双向引用;
  • parent-child 互指;
  • 图结构;
  • 异步任务图。

C++ 对这些东西非常宽容。你可以混用:

  • 裸指针;
  • unique_ptr
  • shared_ptr
  • weak_ptr
  • 引用;
  • handle;
  • ID;
  • arena;
  • intrusive container;
  • object pool。

Rust 也能做,但往往需要:

  • Rc<RefCell<T>>
  • Arc<Mutex<T>>
  • arena;
  • generational index;
  • slotmap;
  • unsafe;
  • 重新设计所有权结构;
  • 更数据导向的架构。

Rust 最终可能让结构更清晰,但前期架构约束更强。而 C++ 允许你直接表达很多 “不干净但现实” 的结构,比如一些很经典但复杂的数据格式。

“歪门邪道” 的价值

有些项目特别能说明 C / C++ 的生命力。ffmpeg 就是典型。ffmpeg 不是一个普通的视频库。它是几十年:

  • 奇怪格式;
  • 历史兼容;
  • 坏文件;
  • 手写 SIMD;
  • 汇编优化;
  • 硬件编解码;
  • 跨平台;
  • 性能压榨;
  • 容错;
  • 黑魔法;
  • 工程妥协;

堆出来的系统怪物。这种东西不是 Rust 写不出来,而是:

它的价值不只是代码本身,而是几十年现实世界的脏活和经验。

Rust 的语言安全当然有吸引力,但要替代 ffmpeg 这种工程怪物,不是语法更现代就够了。类似的还有一些科学计算库、数值库、HPC 库。它们可能有:

  • Fortran 历史接口;
  • C ABI;
  • BLAS / LAPACK 生态;
  • 手写汇编;
  • AVX/AVX2/AVX-512;
  • GPU kernel;
  • CUDA;
  • 编译器特定优化;
  • 数值稳定性经验;
  • 奇怪矩阵布局;
  • cache blocking;
  • SIMD trick;
  • 平台特化;
  • “歪门邪道但有效” 的数学和工程技巧。

这些项目往往不是 “干净的系统工程”,而是 “极端性能工程 + 历史兼容 + 数学技巧 + 硬件细节” 的混合物。C / C++ 很适合这种混沌。

歪门邪道的人也是生态位

Heng Li 那句调侃[1] 很有意思:

Am I switching to Rust? Not in the near future. I enjoy the freedom of shooting myself in the foot.

翻译过来就是:

我会转 Rust 吗?短期不会。我享受开枪打自己脚的自由。

这句话乍看像是在开玩笑,但它抓住了 C / C++ 的一种文化心理。有些程序员确实喜欢,或者确实需要:

  • 控制每一个字节;
  • 看汇编;
  • 手写 allocator;
  • 手动 SIMD;
  • 对齐优化;
  • 利用平台细节;
  • 写 JIT;
  • 做二进制 patch;
  • 维护 ABI;
  • 绕过抽象层;
  • 和编译器斗智斗勇;
  • 为 2% 性能提升重写内存布局;
  • 在危险边缘跳舞。

他们不是不知道危险。他们的态度是:

我知道危险,但我需要这种自由。我愿意承担代价。

Rust 对这类人有时会显得管得太多。Rust 的哲学是:

危险可以做,但你要进入 unsafe,并且把边界圈起来。

C++ 的哲学更像:

世界是开放的,你自己负责。

对大型组织来说,Rust 的哲学更健康。但对某些顶级底层工程师、性能工程师、科学计算库作者、视频编解码专家、游戏引擎黑魔法师来说,C++ 的自由仍然非常有吸引力。而纵观那些改变人类或者创造历史的项目,不少就出自这样一群人之手。

C++ 的真正哲学

C++ 之父 Bjarne Stroustrup 有一段话很值得反复看:

Someone who claims to have a perfect programming language is either a salesman or a fool, or both. [2]

声称自己有完美编程语言的人,要么是销售,要么是傻瓜,或者两者都是。他还说过:

My aim was for C++ to become the second best language for many things.

他的目标不是让 C++ 成为所有事情的最佳语言,而是成为很多事情的第二好语言。这句话一开始会让很多人震惊:

为什么不追求第一?

但这是非常现实的语言哲学。因为:

There can’t be a language that’s best for everything and everybody.

不可能有一门语言对所有事、所有人都是最佳。每个领域理论上都可以有最理想的 DSL:

  • SQL 适合关系查询;
  • shader language 适合 GPU shader;
  • Verilog / VHDL 适合硬件描述;
  • regex 适合文本模式;
  • Python 适合胶水和 AI 上层;
  • Lua 适合嵌入脚本;
  • MATLAB / R 适合统计和数值原型;
  • Rust 适合安全系统组件;
  • C 适合 ABI 和裸机;
  • C++ 适合复杂高性能框架。

但这些理想语言之间有一个问题:

它们怎么互操作?

如果每个领域都用自己的小语言,系统怎么构建?怎么调试?怎么部署?怎么共享内存?怎么组合成一个大型产品?Bjarne 的回答是:

需要一个通用框架,C++ 就试图成为这样的框架。

C++ 的强项不是每个点都最优雅,而是它可以承载各种风格:

  • C 风格;
  • 面向对象;
  • 泛型;
  • 函数式;
  • 模板元编程;
  • 编译期计算;
  • 宏;
  • RAII;
  • 异常;
  • 无异常;
  • RTTI;
  • 无 RTTI;
  • 裸指针;
  • 智能指针;
  • 手写内存池;
  • 嵌入式 DSL;
  • 平台 hack。

C++ 里面可以长出:

  • Eigen;
  • Qt;
  • Unreal;
  • LLVM;
  • Boost;
  • ranges;
  • coroutine framework;
  • allocator framework;
  • expression templates;
  • 游戏对象系统;
  • GUI 框架;
  • 编译期 DSL;
  • GPU 抽象层。

这些东西不一定美,但它们能装下现实世界的复杂性。所以 C++ 的哲学可以概括为:

我不保证你不受伤,但我给你最大表达空间。

Rust 的哲学则是:

我尽量不让你受伤,但你要按照我的规则表达问题。

这不是简单的先进和落后。这是两种工程哲学。

未来格局

所以未来最可能的格局不是:

Rust 消灭 C++。

也不是:

C++ 不受影响。

而是:

C / C++ 被系统性分流,Rust 在新系统工程里主流化,C++ 保留复杂高性能王牌区,C 保留底层边界和 ABI。

Rust 的主战场

Rust 最容易成功的地方是:

需要接近 C/C++ 的性能和控制力,但又不想继续承担 C/C++ 内存安全风险的新系统项目。

包括:

  • 新网络基础设施;
  • 新代理 / 网关;
  • 新存储组件;
  • 新数据库组件;
  • 新安全边界组件;
  • 新解析器;
  • 新虚拟化组件;
  • 新容器基础设施;
  • 新 WebAssembly runtime;
  • 新 CLI;
  • 新构建工具;
  • 新包管理器;
  • 新开发工具链;
  • 部分 OS 组件;
  • 部分中高端嵌入式;
  • 云基础设施;
  • 高性能服务。

这些地方 Rust 会越来越像 “默认合理选项”。

C++ 的保留地

C++ 仍然很强的地方包括:

  • 游戏引擎;
  • 图形渲染;
  • 音视频编解码;
  • ffmpeg 这类工程怪物;
  • 复杂高性能库;
  • HPC;
  • 科学计算底层;
  • ML runtime;
  • 物理仿真;
  • CAD/CAE/EDA;
  • 高频交易;
  • 浏览器部分模块;
  • 工业软件;
  • 大型桌面软件;
  • 需要大量底层 hack、平台特化和历史兼容的系统。

这些地方 C++ 的自由、抽象能力和黑魔法容忍度仍然非常有价值。

C 的保留地

C 仍然会长期存在于:

  • C ABI;
  • libc;
  • syscall 接口;
  • bootloader;
  • 裸机;
  • 芯片 SDK;
  • 内核极底层;
  • 语言 runtime;
  • 动态库接口;
  • 嵌入式小固件;
  • 硬件寄存器定义;
  • 平台胶水;
  • freestanding 环境。

C 的角色会从很多项目的实现语言,逐渐更多变成:

底层公共边界语言。

其他语言的领地

很多领域本来就不该由 Rust 或 C++ 主导:

  • 企业业务:Java、C#、Kotlin;
  • 云服务:Go、Java、C#;
  • AI 上层:Python;
  • 数据分析:Python、R、SQL;
  • 前端:TypeScript;
  • 移动端:Swift、Kotlin、Dart;
  • 脚本自动化:Python、Shell;
  • AI / HPC 新路径:Mojo、Triton、CUDA;
  • 平台应用:Swift、Kotlin、C#。
  • ……

Rust 和 C++,以及其它的所有语言,甚至可以大胆预测未来的新兴语言,都不是所有地方的最佳答案。这正好印证 Bjarne 那句话:

没有一门语言适合所有事情和所有人。

作为 C++ 开发者真正应该学什么?

这个讨论最后落到职业发展上。作为 C++ 开发者,未来最危险的定位是:

我就是写 C++ 的。

因为 “普通 C++ 开发” 会越来越尴尬。如果只是:

  • 会写 class;
  • 会用 STL;
  • 会一点模板;
  • 会业务逻辑;
  • 不懂系统;
  • 不懂性能;
  • 不懂内存模型;
  • 不懂 ABI;
  • 不懂工具链;
  • 不懂安全;
  • 不懂并发;
  • 不懂其他语言生态;

那么不只是 Rust,其实早在多年前,C++ 的很多项目就正在被 Java、Go、C#、Rust、Python、TypeScript 分走。对于这样的同志,我反而建议费点心思,学习一下 Rust。C++ 开发者未来真正值钱的地方在深水区。

学 Rust,补内存安全思维

即使以后主要写 C++,也应该学 Rust。

不是因为你一定要转 Rust,而是 Rust 会训练你重新理解:

  • ownership;
  • borrowing;
  • lifetime;
  • move semantics;
  • aliasing;
  • shared mutability;
  • data race;
  • API 如何表达所有权;
  • unsafe 边界怎么缩小。

学完 Rust 再回头写 C++,你会更敏感地问:

  • 谁拥有这个对象?
  • 谁只是观察者?
  • 谁可以修改?
  • 生命周期在哪里结束?
  • 这个引用会不会悬垂?
  • 这里应该用 unique_ptr 还是 shared_ptr
  • 这里能不能用 spanstring_view
  • 这个对象是否应该 move-only?
  • 这段并发代码是否有 data race?
  • 这个 API 是否让调用者容易误用?

Rust 对 C++ 开发者最大的价值,不只是多一门语言,而是培养一种更严格的所有权和生命周期意识。

深挖 C++ 的王牌区能力

C++ 开发者应该强化:

  • 性能工程;
  • 系统编程;
  • 内存模型;
  • 并发;
  • ABI;
  • 编译链接;
  • 工具链;
  • crash debugging;
  • sanitizers;
  • fuzzing;
  • profiling;
  • SIMD;
  • allocator;
  • cache locality;
  • lock-free;
  • NUMA;
  • CPU pipeline;
  • branch prediction。

未来值钱的 C++ 工程师,不是会写多少语法,而是能回答:

  • 为什么这段代码慢?
  • 为什么 cache miss?
  • 为什么 false sharing?
  • 为什么这段代码有 UB?
  • 为什么线上 core dump?
  • 为什么链接失败?
  • 为什么 ABI 不兼容?
  • 为什么这个 allocator 导致性能抖动?
  • 为什么这个锁成为瓶颈?
  • 为什么这个数据结构不适合 CPU cache?

这些能力才是护城河。

选一个行业纵深

C++ 最好和一个硬领域绑定。

比如:

  • 音视频:ffmpeg、codec、container format、SIMD;
  • 游戏:引擎、ECS、渲染、资源系统、脚本系统;
  • 数据库:存储引擎、查询执行、LSM、B-tree;
  • 网络:协议栈、proxy、TLS、DPDK、io_uring;
  • 编译器:LLVM、IR、优化、代码生成;
  • 图形:Vulkan、Metal、DirectX、shader;
  • ML runtime:tensor、kernel、CUDA、ONNX Runtime;
  • 嵌入式:RTOS、裸机、驱动、芯片 SDK;
  • 低延迟系统:交易、NUMA、lock-free、内存布局;
  • 科学计算:BLAS、LAPACK、SIMD、数值稳定性。

C++ 的未来不在泛泛而谈,而在深入复杂系统。

形成 T 型能力

横向上,要懂多语言选型:

  • Rust:安全系统工程;
  • C:ABI 和极底层;
  • Go:云原生、平台服务;
  • Python:AI、脚本、胶水;
  • TypeScript:前端和工具链;
  • Java / C#:企业和业务系统;
  • Zig / Mojo:潜在未来方向。

纵向上,要有 C++ 深水区能力。

成熟的 C++ 开发者不是到处推 C++,而是知道:

什么时候应该用 C++,什么时候不该用 C++。

这很重要。

未来不是取代,而是重新分工

这场讨论最终不应该落在 “Rust 会不会取代 C++” 这种简单问题上。更准确的结论是:

Rust 会在新系统工程里成为主流力量,尤其会强烈分流安全敏感的新项目。
C++ 会失去很多本来不该属于它的新增项目,但仍然守住复杂高性能、底层黑魔法、历史兼容和大型工程怪物这些王牌领域。
C 会长期保留 ABI、裸机、系统边界、平台胶水这些位置。
其他语言会在业务、AI、前端、移动、脚本等领域继续比 Rust 和 C++ 更合适。

Rust 的胜利,不是让 C/C++ 消失。Rust 的胜利是让未来很多新系统项目不再无脑选择 C/C++。

C++ 的生命力,也不只是历史包袱。它确实拥有一种极其罕见的能力:它能容纳复杂、高性能、混乱、充满 hack 的现实工程。

C 的生命力,则在于它足够薄,足够接近系统边界,是事实上的底层公共语言。

所以未来最可能的状态是:

Rust 成为新系统工程的重要主流;
C++ 成为复杂高性能工程和黑魔法系统的硬核工具;
C 成为 ABI、裸机和底层边界的公共语言;
其他语言在各自更适合的领域继续胜出。

对 C++ 开发者来说,最好的策略不是恐惧 Rust,也不是鄙视 Rust,而是:

用 Rust 补安全思维,
用 C++ 深挖性能和底层,
用系统知识构建护城河,
再选一个行业方向扎进去。

这不是语言战争的结束。

这只是软件工业开始更成熟地分配工具。

这何尝不是一件好事?


  1. What high-performance language to learn? ↩︎

  2. Bjarne Stroustrup Quotes ↩︎