快十年了,Rust 怎么还没有取代C++?在9月27日的【开源漫谈】第14期节目中,开源中国OSChina邀请到了马全一、冯洋以及张汉东三位 Rust 专家深入讨论了这一问题。
马全一:江湖人称 “马道长”,目前在华为负责Rust编程语言在国内的生态建设和推广,曾运营openEuler项目并推动Docker容器社区的发展。
张汉东:资深Rust专家,著有《Rust 编程之道》一书,参与了不少开源项目,当前主要工作是承接Rust咨询。
冯洋:南京大学计算机科学与技术系助理研究员,主要研究方向是复杂软件系统的质量保障,同时在南京大学教授编译原理这一课程。研究Rust已有两年,主要集中在两个方向:一是以Rust为核心支撑的软件工程技术研发,二是带领团队基于Rust的编译技术做一些尝试。
以下内容根据直播整理:
“safe C++”新草案
张汉东:今天讨论的主题是为什么C++在过去十年里没有被取代。首先,我们需要定义什么是“取代”。有一种观点是将所有的C++程序用Rust重写,但这是不可能的,因为C++已经发展了多年,拥有庞大的代码遗产。
然而,我们可以看到一些进展。例如,某些基础组件,如浏览器的V8引擎,已经完全用Rust绑定,并且这种绑定已经稳定。在社区中,这被称为“绣化”,意味着有了稳定的Rust层,当大家使用V8内核时,可以顺利地推荐使用Rust。
另外,C++最近提出了一个名为”safe C++”的新草案,旨在提升语言的安全性。这在一定程度上是受到Rust语言影响力的结果。如果没有Rust,C++可能不会那么重视安全性,也不会有这个草案。在过去两年中,像美国政府和安全部门一直在呼吁使用内存安全的语言,因为内存安全的需求非常迫切。包括在过去两年的许多新闻中,政府文件甚至将C++标记为不安全的语言,因为C++的类型不安全,存在许多安全问题。
总的来说,虽然C++没有被完全取代,但Rust语言的出现确实推动了C++向更安全、更现代的方向发展。这种影响体现在C++的新草案中,以及一些关键组件开始使用Rust进行重写或绑定。这是一个渐进的过程,而不是一夜之间的彻底替换。
Rust怎么实现内存安全?
张汉东:Rust实现内存安全的方法可以概括为多层次的设计。首先,Rust拥有一个严谨的类型系统,它通过分析和归类C和C++等语言内存安全错误的原因,避免了类型混淆的问题。在这个类型系统的基础上,Rust引入了所有权规则,规定了类型在底层内存的大小和布局,并通过编译器检查来规范类型的行为,以此达到内存安全管理。此外,Rust还通过所有权、借用检查和生命周期检查等机制来管理指针的安全,替代了传统的垃圾收集(GC)和手动内存管理方式,从而确保内存安全。
马全一:总结就是,靠一大堆机制来实现这个内存安全。冯洋,能否从形式化验证这个角度来给大家讲一下Rust 如何确保内存安全?
冯洋:形式化验证,就是通过数学推导的方式来验证一个程序的行为是否满足预定需求或预定约束。一般情况下,通过形式化验证的程序,我们可以认为它是相对正确的。但形式化验证效率比较低,通常情况下,数百万行甚至数千万行代码的大型程序都很少采用这一方式。
Rust的内存模型在safe的环境下绝对安全,这是通过形式化验证的。但是,rust的内存模型,它总是要有程序员去把它实现到编译器里面,成为编译器里面的一个规则或者函数,这些代码是没有通过形式化验证的。这两者不矛盾。
马全一: Rust的这套规则通过了形式化验证.只要你按这个规则来,应该是内存安全的。但是在你实现的过程中,可能会写出bug,出现内存不安全的问题,但是已经解决了以前大部分的内存安全问题。
C++的RAII与Rust的所有权机制
张汉东:从实现机制来看,Rust的所有权机制类似于C++的RAII(资源获取即初始化),但Rust强制要求使用,这是编译时强制的,而C++是可选的,依赖于编程规范来引导开发者使用,因此存在一定的风险。
C++的新草案借鉴了Rust的安全模型,定义了什么是安全。内存安全的语言必须防止未定义行为,这与Rust的内存安全定义一致。草案还强调了当检测到未定义行为时,无论是开发者还是调用者都应受到编译器的检查。
Safe C++采用了与Rust相同的安全模型,将代码分为安全类别,并提供了安全的上下文,例如生命周期安全,防止悬垂指针,以及类型安全,强调了类型安全是Rust内存安全的基础。C++不是类型安全语言,因此它通过修改对象模型来解决安全问题。
线程安全也属于内存安全的范畴,因为多线程写状态可能会发生数据竞争。运行时检查也是必要的,例如数组越界和计算溢出,这些在Rust中通过API避免了未定义行为。
C++草案还提到了如何设计安全模型,包括借用检查,这是Rust安全模型的一部分。C++引入了对安全操作的边界提示,要求开发者保证内存安全的操作,而不是完全依赖编译器。
从2024年开始学习C++的人可能会学习Rust的安全模型,这表明Rust对C++的影响力很大,甚至可以说Rust在某种程度上已经取代了C++,至少在安全模型方面是这样。
Fust for Linux 进展
马全一:Rust for Linux这个项目已经好几年了。资助Linux内核中Rust语言开发的公司包括AWS、华为、微软和Google。要知道,一项技术从被引入Linux内核到成熟并被广泛使用,可能需要长达十年的时间。以容器技术为例,从出现到被广泛接受和使用,大约经历了十年的时间,这期间Google和IBM的工程师们不断努力。对于Rust语言在Linux内核中的应用,虽然已经讨论了两三年,但这个过程需要时间,我们应该保持耐心。今年,Google有一个名为Binder的项目,它使用Rust重写了安卓系统中的跨进程通信模块,这个模块原本是用C语言编写的,存在很多问题,但现在Binder项目已经成功集成到安卓的主线中,这证明了Rust语言在内核开发中的可行性和重要性。尽管如此,是否全部重写现有代码或者如何进行,可能还需要很长时间来决定和实施。
张汉东:Linux内核维护者在9月3日的演讲中提到了这一进展,并且提到了Rust语言在Linux内核中的应用。从2021年到2024年,社区的邮件列表数量已经达到了536,而Linux用户的即时聊天社群在2024年7月和8月已经增长到了754个成员,显示出社区的不断壮大。
尽管有些C++维护者反对Rust语言进入Linux内核,但这种技术转变是不可避免的。毕竟,人们已经习惯了使用C语言几十年,突然转向Rust语言可能会让人感到不适,这是可以理解的。然而,Linus Torvalds已经表态,预计在明年会有更多的驱动程序或程序使用Rust语言。
目前,有许多赞助商支持这项工作,包括GCC Rust前端项目,该项目旨在在GCC编译器上重写一个Rust语言前端,以及将Rust的前端与GCC后端结合的项目,这些项目都在快速进展中。这些工作可以让Rust语言更好地利用GCC的生态系统。
总的来说,Rust语言在Linux内核中的应用是一个缓慢但必然的趋势。预计在不久的将来,我们会看到更多的应用案例。相关的链接和详细信息将会分享给大家,以便更深入地了解这一领域的最新进展。
冯洋:C++之父在其关于C++发展的四篇文章中提到,任何一种编程语言要获得成功和繁荣,都必须解决一个具体的问题。如果一种语言没有解决实际问题,它就无法繁荣。例如,Python解决了编程的易用性问题,Java通过JVM解决了可移植性问题,而C语言的出现则让程序员不再需要编写汇编语言。Rust语言则是为了解决C语言中的内存安全问题而设计的。这些例子都证明了,一种语言要发展起来,必须有一个特定的问题或特定的使用场景,促使人们去使用它,这样它才能繁荣起来,这是历史上已经被证明的事实。
Rust有什么杀手级应用吗?
马全一:所谓的杀手级应用,就像Go语言一样,有一个标志性项目推动了整个语言的发展。例如,我早期在国内开始涉足Docker和kubernetes,见证了Go语言的崛起。可能大家不知道,许世伟是最早在中国推广Go语言的人,他在2012年甚至更早的时候就开始使用Go,他的公司七牛云的很多系统都是用Go编写的。随着kubernetes和云计算的发展,国内的大型云计算厂商基本上都在使用Go进行开发。这就是一个项目带动了一个产业的发展,从而推动了语言的进步。
而Rust目前在我看来,还没有这样一个体系。现在最热门的是AI领域,虽然我看过一些与AI相关的项目,张汉东老师也分享过,但Rust语言在这些项目中的影响力并不明显。
因此,我也希望Rust语言能够出现一个像docker那样的工具,一个能够改变所有开发者日常工作的杀手级应用,但目前这样的应用还没有出现。
张汉东:大家之所以对Rust语言感兴趣,主要是因为希望它能带来大量的工作岗位。目前,Rust主要应用于系统和基础设施的改造。而在应用开发方面,Rust正逐渐崭露头角,例如纯Rust编写的全站框架,这种跨平台的全站框架有可能替代Flutter。我所参与的开源项目,如E GUI等框架,虽然还在发展阶段,尚未成熟,但已显示出潜力。
此外,Rust在游戏引擎方面的应用也值得关注,虽然这些引擎可能还不能算作完整的游戏,但它们在工具层面的表现非常出色。随着这些框架和工具的不断完善,未来可能会出现杀手级应用。
在AI领域,目前尚未看到Rust有显著的推动作用。但在解决实际问题方面,Rust的应用正逐渐增多。AI技术正在从传统的Python加C++的组合,逐步向Python加Rust的技术栈迁移。虽然目前还未出现杀手级应用,但我认为Rust正在朝着这个方向发展。
对Rust的未来怎么看?
马全一:我目前的工作是推广Rust生态。我认为,一个编程语言或开源项目的发展,可以以十年的周期来看。我参与Docker,从2013年到2023年,接近十年。我认为一个成功的开源项目,从它诞生到完全融入大家的日常工作,需要时间,而且通常是在天时、地利、人和的交汇点上,这也大约是一个十年的周期。因此,项目初期的发展曲线,直到它被广泛应用的那段时期,可以认为是不那么重要的。
从Rust基金会成立的那一年也就是2021年来看,我认为Rust的发展还有很长的路要走。Rust成为大家日常工作的一部分,这只是一个开始,可以说是第一个十年的第一步。所以,如果你深入学习了Rust,并且认为它符合你对计算机科学的理解和愿景,那么我认为你可以坚持使用它。
再过三五年,你可能会看到自己的成果。而不是想着今天学习了,明天就能找到一份薪资增加50%的工作。这是种不切实际的幻想。
张汉东:其实我可以现身说法。2015年Rust 1.0版本刚发布时,我开始学习Rust。那时候,几乎没有Rust相关的工作机会。
然而,经过了差不多十年,也就是到了2020年左右,我们可以看到Rust在各个领域开始被广泛使用,这已经是一个非常不错的成就了。Rust甚至对有着40多年历史的C++语言产生了影响——发布安全草案,我认为这十年间Rust的发展已经达到了一个重要的里程碑。接下来的十年,Rust的发展前景肯定是一片光明,特别是在系统和基础设施领域,它肯定会有很大的发展潜力。
冯洋:我个人对Rust的发展非常看好。然而“取代”这个词可能有些过于强烈。我不认为Rust会完全取代C和C++。也就是说,Rust出现之后,并不意味着C和C++就不再被使用。
考虑到目前全球可能有数十亿行的历史代码,这个数字是我随便说的,没有经过调研。这意味着存在大量的历史遗留代码,因此C和C++不可能完全退出这个行业。它们将会与Rust长期共存,在未来的很长一段时间内,它们将相互影响。
Rust的进化已经在影响C和C++的进化,这一点已经得到了充分的证明。C++的一些基本机制或进化可能会成为Rust的特性。
我认为在下一个十年,Rust依然不可能完全取代C和C++。但是,正如张汉东老师提到的“取代”,Rust的机制可能促使C和C++提出了安全性草案,这实际上也可以被理解为一种形式的“替代”。这是我对此的理解。
张汉东: 所以,我们需要明确“取代”这个词的定义。比如说,如果有新的项目启动,让你在C++和Rust之间做出选择,如果你选择了Rust,那么在这个情境下,Rust就取代了C++。换句话说,对于这个新的项目,Rust成为了首选语言。
然而,如果说要将所有现有的C++项目都完全重写为Rust,那么这种意义上的“取代”是不可能发生的。因为将所有C++代码库转换为Rust是一个极其庞大且不切实际的任务,所以从这个角度来看,Rust并不会完全取代C++。
马全一: 我参与的OSS Compass项目有一个列表,这个列表收集了GitHub和Gitee上最活跃的仓库。我花了一个多月的时间,因为经常被封IP,最终下载了大约12个T的代码。我对这些代码进行了分析。结果显示,在新增代码方面,Rust的使用趋势是上升的。C++的新增代码也在增长,特别是在AI领域爆发期间,C++的新增代码量有一个显著的高峰,之后又有所下降。尽管Rust的增长曲线仍然位于C++之下,但从这些趋势来看,我认为在十年内,Rust和C++在新增代码量上可能会达到一个持平的水平。
因此,我认为Rust并不是在取代C++,而是逐渐占据了一部分市场。这部分市场是Rust非常合适的使用场景。目前,我们看不到哪个特定场景特别适合Rust。例如,许多国内外的开源项目都在使用Rust编写数据库,但如果仔细观察它们的架构,会发现一个核心问题:在最底层的KV存储部分,通常还是使用C++编写的rocksdb存储引擎。这些数据库项目通常不会用Rust重写底层引擎,而是在rocksdb之上做一层封装。
尽管上层应用领域变得丰富,如关系数据库、图数据库、AI向量数据库等,使用Rust进行这些数据库的上层管理和开发是没有问题的,但底层核心引擎的重写却鲜有人尝试,且尚未达到替代rocksdb的程度。
在生态发展的过程中,Rust是逐渐成长的。我同意之前的观点,第一,我认为Rust不会取代C++;第二,将来Rust会在市场中占有一席之地,与C++三分天下。对于Rust来说,这已经是成功了。
张汉东:当然,还有一些特定领域,比如安全关键领域,这些领域的趋势并不仅仅是自然发生的状态。例如,美国政府提出C++安全草案是因为,政府有强制性的要求,需要选择更安全的编程语言。在这些领域中,有些公司的领导层可能会做出决策,明确要求在安全关键的领域使用Rust。
例如,在NTPI(网络物理系统)和实时系统这些安全关键的领域,Rust因其安全性而受到青睐。现在,谷歌已经将某些系统重写为Rust。这表明在这些领域中,选择Rust的概率可能会因为人为的因素而更高。
这些决策可能会加速Rust在这些特定领域的采纳,不仅仅是因为市场的自然选择,还因为政策和公司战略的推动。因此,Rust在这些安全关键领域的应用可能会比其他领域更快地增长。
马全一:从运营的角度来看,我们称之为自上而下的引导。政府机构在这方面扮演了重要角色,我要提到的是华为,华为也在进行类似的工作。学校和华为、教育部、工信部合作开设Rust课程,目的是希望从上至下地引导大家学习和使用Rust。
自发的趋势可能需要十年的时间,这个增长曲线才会逐渐上升,尤其是在市场的新增代码方面。我必须强调的是,我们讨论的是新增代码,比如新建项目。如果你考虑的是历史积累的代码,就像张老师刚才所说的,你将新旧代码放在一起比较,那么我认为即使在20年后,这两者也可能无法相提并论。
微信扫码,观看直播回放: