作者shyin7089 (希音)
看板C_and_CPP
标题Re: [讨论] Rust与C++
时间Tue Jun 27 09:02:09 2023
※ 引述《icetofux ()》之铭言:
: 最近看到一则windows以Rust改写部分程式的新闻,仔细一查发现Linux似乎也打算将Rust作为内核开发的第二语言,让我对Rust这个语言产生很大的兴趣。
: 我最先学会的语言是C,後来在学习物件导向的时候开始接触到C++,对於C++提供的语言特性及STL印象深刻。虽然不能说写的非常好,但感觉C++强化了很多C在记忆体管理上容易出现问题的地方。目前如果环境许可,C++往往是我会优先选择的语言之一。
: 快速搜寻了一下Rust及C++的比较,大部分都是着重在将两个语言的优缺点条列比较,比如Rust在记忆体管理跟编译讯息上更为突出,而C++则是保持对C的相容跟编译速度更为出色,编译出来的执行效率两者似乎在伯仲之间,都非常的优秀。
: 但是看了几项比较资料後,却没有发现两大作业系统选择了较为年轻的Rust而非长时间发展的C++的关键原因。请问有对Rust较为熟悉的先进可以帮忙解惑吗?
: 谢谢。
首先,先澄清一下以避免误解。
Linux 核心的内部主要子系统并没有转以 Rust 撰写,而是以 module 的形式,依附於现
有的核心架构,以 Rust 语言开发新的 driver 。
OK ,回到正题。
刚好在前阵子也看到 Linus 对 Rust 跟 C++ 的一些想法,挺有趣在此分享一下。
简单来说, Linux 不采用 C++ 的原因是因为 "C++ solves _none_ of the C issues,
and only makes things worse. It really is a crap language."。
而 Rust 会被采纳是因为它很明显的针对了 C 语言的记忆体缺陷有很大的改善,反而是
C++ 提出改进,老实说在 C 语言 + GCC (GNU extension) 的组合拳下也并不是实作不出来。
在 1992 年跟 2004 年时,不管是核心或是 module ,都有人想用 C++ 去撰写、改写 [1]。
在此引述当时 Linus 的留言:
The fact is, C++ compilers are not trustworthy. They were even worse in
1992, but some fundamental facts haven't changed:
- the whole C++ exception handling thing is fundamentally broken. It's
_especially_ broken for kernels.
- any compiler or language that likes to hide things like memory
allocations behind your back just isn't a good choice for a kernel.
- you can write object-oriented code (useful for filesystems etc) in C,
_without_ the crap that is C++.
In general, I'd say that anybody who designs his kernel modules for C++ is
either
(a) looking for problems
(b) a C++ bigot that can't see what he is writing is really just C anyway
(c) was given an assignment in CS class to do so.
Feel free to make up (d).
但这不是说所有 C++ 已有的 feature 都是垃圾,只是 Linus 对於作业系统的撰写有一
定严格要求程式码要能更清楚的阐明它的执行步骤,并且对於物件以及记忆体的操作要够
明确。
这点可以从近期要引入 pointer and lock guards [2] 的讨论中看出端倪 [8]。
除此之外,其实撰写核心的 C 语言也有其限制,跟一般在 userspace 的 C 不太一样。
比如不能使用 floating point, setjmp/longjmp 等,即便他们是 standard 。
因此,对於 C++ 而言, Linus 只是讨厌有问题的程式码以及会让程式码出问题的 C++
、它的函式库 [7] 以及它的(不成熟的)编译器而已。而开发者们则是对於 C++ 的引入,在
思考时所想的坏处多到以至於不想去验证它的好处有哪些而已 [5][6]。引述至 [7] :
C++ leads to really really bad design choices. You invariably start using
the "nice" library features of the language like STL and Boost and other
total and utter crap, that may "help" you program, but causes:
- infinite amounts of pain when they don't work (and anybody who tells me
that STL and especially Boost are stable and portable is just so full
of BS that it's not even funny)
- inefficient abstracted programming models where two years down the road
you notice that some abstraction wasn't very efficient, but now all
your code depends on all the nice object models around it, and you
cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and
portable C++ ends up to limit yourself to all the things that are
basically available in C. And limiting your project to C means that people
don't screw that up, and also means that you get a lot of programmers that
do actually understand low-level issues and don't screw things up with any
idiotic "object model" crap.
而在近一次的访谈中 [4], Linus 也有被问到为何不使用 C++ ,以下是访谈片段:
By using Rust in the Linux kernel, our hope is that:
- New code written in Rust has a reduced risk of memory safety bugs, data
races and logic bugs overall, thanks to the language properties mentioned
below;
- Maintainers are more confident in refactoring and accepting patches for
modules, thanks to the safe subset of Rust;
- New drivers and modules become easier to write, thanks to abstractions that
are easier to reason about, based on modern language features, as well as
backed by detailed documentation;
More people get involved overall in developing the kernel, thanks to the
usage of a modern language; and
- By taking advantage of Rust tooling, we keep enforcing the documentation
guidelines we have established so far in the project. For instance, we
require having all public APIs, safety preconditions, `unsafe` blocks and
type invariants documented.
可以看到, Rust 的引入不仅可以解决记忆体安全问题;让 driver maintainer 更容易接
受新的 patch ; 强制撰写 documentation 等,都是一些就算引入 C++ 後也不会有的改
进。
尤其是 doc 的部分, Rust 真的做得蛮好的。
总而言之,因为语言特性、编译器的不成熟, C++ 不适合 OS kernel 的开发,而
memory safety 的 Rust 适合。
[1]
https://lore.kernel.org/all/[email protected]/T/#u
[2]
https://lore.kernel.org/all/[email protected]/T/#u
[3]
https://lore.kernel.org/rcu/CAHk-=wgaSkM4fjdP9dcdXQpLLjxW43ykgLA=FgzyHpyHayz8ww@mail.gmail.com/
[4]
https://itwire.com/business-it-news/open-source/rust-support-in-linux-may-be-possible-by-5-14-release-torvalds.html
[5]
https://lore.kernel.org/all/[email protected]/
[6]
https://lore.kernel.org/all/[email protected]/
[7]
https://harmful.cat-v.org/software/c++/linus
[8]
https://lore.kernel.org/lkml/CAHk-=wgaSkM4fjdP9dcdXQpLLjxW43ykgLA=FgzyHpyHayz8ww@mail.gmail.com/
--
∴ ▃▄ ▃▆▲∥ ▲▊▂▃▂▎ ▼▍ ▼ ◢▊ ◢ ▎▎ ▉▉▏ ▍▍▲
▄▇▄▃▅▲ / ▲ ▼▼▊▅ ◤ ▎ ▼ ﹀▂▃▃▂▏▲▎▎ ▉ ◤Saber
▂▁▼▃▄▆▁▄▲∕ ◢▼\ ▅▃▎ ◤ ,︻ ◣ ▼◢▏ ▉▋▏ Lily
▇▆ ▃▆ ,▲∕ #▏ ▄▄"▏▊▃▆ ↗、▅▉▃▼◢ # ▲▏▊▉▎
▂▄ ╱▲ / ▲▉˙"▅▂▲ ▎▅▊ ▲ ∕▲ ▋▊▏ ◤
◤ -" ▲ ∕ ∕▲\▎ ▅▄▆▲ /▲▉ ▍ ◢
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.110.9.95 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1687827737.A.866.html
※ 编辑: shyin7089 (123.110.9.95 台湾), 06/27/2023 09:25:51
1F:推 pponywong: 推 c++ 这几年的发展 的确跟kernel 面对的问题不一样 06/27 11:35
2F:推 Schottky: 还真没注意过 kernel 不能用 floating point 这回事 06/27 15:31
主要是因为不能保证所有硬体都支援浮点数运算,因此才加以限制。
但也因此采用了定点数运算,也算是另一种折衷方案吧。
3F:推 james732: Linus回答这个问题应该答到很腻了XD 06/27 16:34
看起来是XDD
不过也可以从同个问题看到,跟十几年前相比, Linus 的脾气有变好了许多XDD
※ 编辑: shyin7089 (123.110.9.95 台湾), 06/28/2023 00:06:42
4F:推 DaOppaiLoli: 推推长知识了 06/28 00:07
5F:推 rnoro: 真是好文!学到很多XD 06/28 00:18
6F:→ james732: 至少他没有说Fuck C++ XD 06/28 00:29
7F:→ tinlans: 可能近年都在写交易系统的关系, 06/28 01:45
8F:→ tinlans: 比起 Rust 我更关注 Carbon 06/28 01:45
9F:→ tinlans: 如果还留在半导体业我大概也会直接押宝 Rust 06/28 01:48
Carbon 我倒是很少关注,不太确定它对於 C++ 补强了哪些方向。
不过,刚刚我看了 2022 的 Carbon Language: Syntax and trade-offs
https://www.youtube.com/watch?v=9Y2ivB8VaIs
在前段 9 到 11 分左右,利用 printer<circle>(radius) 可以是
function call, constructor call, variable declarartion, and comparison
完美的说明了 C++ 在撰写上 context is king 的不明确性XDDD
10F:推 icetofux: 谢谢你的说明,完整的解答了我的疑惑。 06/28 08:20
不会 :)
※ 编辑: shyin7089 (123.110.9.95 台湾), 06/28/2023 09:00:27
11F:推 laxw: 推好文 06/28 17:30
12F:推 kyushu: 请问rust跟c++互call方便吗?因爲现有c++ open source 还 06/28 18:01
13F:→ kyushu: 是比较多,想改谢rust call c++ library 06/28 18:01
14F:→ kyushu: 改写成rust 乎叫 c++ library 06/28 18:01
16F:推 v86861062: 推推 06/29 12:57
17F:推 dzwei: 互抠是可以治标,但最根本的还是那句话:Rewriting everyth 06/29 15:06
18F:→ dzwei: ing with rust 06/29 15:06
19F:推 wulouise: rust的好处就是你从头开始写就少很多问题,carbon则是在 06/30 21:46
20F:→ wulouise: 你已经有c++的情况下要怎麽让问题减少 06/30 21:46
21F:→ wulouise: rust支援c interop吧,但是支援之後那边就成了会出问题 06/30 21:47
22F:→ wulouise: 的地方 06/30 21:47
23F:推 Schottky: 同意 Linus 的脾气变好很多 XD 07/01 22:09
24F:推 Richun: 我记得刚开始rust想进入kernel时,Linus有先批评rust的错 07/01 22:39
25F:→ Richun: 误处理,主要是有些lib在出错误的情况下就直接panic掉,在 07/01 22:41
26F:→ Richun: kernel里面这处理方法不能被接受,後来怎改的我就不知道。 07/01 22:41
27F:→ saladim: 这句话: "...反而是C++ 提出改进,老实说在 C 语言 +..." 07/08 03:58
28F:→ saladim: 是说C++提出改进而不是Rust?? 07/08 03:58
29F:→ shyin7089: 对。例如 OO 的概念, C 语言也可以实作出来。 07/11 19:13
30F:推 dzwei: rust的trait概念也跟x/c++的oo不太一样就是XD 07/12 00:19
31F:推 dmeiki: 推 08/21 16:35