Re: [討論] Rust與C++
※ 引述《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/Pine.LNX.4.58.0401192241080.2311@home.osdl.org/T/#u
[2] https://lore.kernel.org/all/20230526150549.250372621@infradead.org/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/400CF96B.8020109@samwel.tk/
[6] https://lore.kernel.org/all/400D070B.2070407@samwel.tk/
[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://www.ptt.cc/bbs/C_and_CPP/M.1687827737.A.866.html
※ 編輯: shyin7089 (123.110.9.95 臺灣), 06/27/2023 09:25:51
推
06/27 11:35,
1年前
, 1F
06/27 11:35, 1F
推
06/27 15:31,
1年前
, 2F
06/27 15:31, 2F
主要是因為不能保證所有硬體都支援浮點數運算,因此才加以限制。
但也因此採用了定點數運算,也算是另一種折衷方案吧。
推
06/27 16:34,
1年前
, 3F
06/27 16:34, 3F
看起來是XDD
不過也可以從同個問題看到,跟十幾年前相比, Linus 的脾氣有變好了許多XDD
※ 編輯: shyin7089 (123.110.9.95 臺灣), 06/28/2023 00:06:42
推
06/28 00:07,
1年前
, 4F
06/28 00:07, 4F
推
06/28 00:18,
1年前
, 5F
06/28 00:18, 5F
→
06/28 00:29,
1年前
, 6F
06/28 00:29, 6F
→
06/28 01:45,
1年前
, 7F
06/28 01:45, 7F
→
06/28 01:45,
1年前
, 8F
06/28 01:45, 8F
→
06/28 01:48,
1年前
, 9F
06/28 01:48, 9F
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
推
06/28 08:20,
1年前
, 10F
06/28 08:20, 10F
不會 :)
※ 編輯: shyin7089 (123.110.9.95 臺灣), 06/28/2023 09:00:27
推
06/28 17:30,
1年前
, 11F
06/28 17:30, 11F
推
06/28 18:01,
1年前
, 12F
06/28 18:01, 12F
→
06/28 18:01,
1年前
, 13F
06/28 18:01, 13F
→
06/28 18:01,
1年前
, 14F
06/28 18:01, 14F
推
06/28 20:56,
1年前
, 15F
06/28 20:56, 15F
推
06/29 12:57,
1年前
, 16F
06/29 12:57, 16F
推
06/29 15:06,
1年前
, 17F
06/29 15:06, 17F
→
06/29 15:06,
1年前
, 18F
06/29 15:06, 18F
推
06/30 21:46,
1年前
, 19F
06/30 21:46, 19F
→
06/30 21:46,
1年前
, 20F
06/30 21:46, 20F
→
06/30 21:47,
1年前
, 21F
06/30 21:47, 21F
→
06/30 21:47,
1年前
, 22F
06/30 21:47, 22F
推
07/01 22:09,
1年前
, 23F
07/01 22:09, 23F
推
07/01 22:39,
1年前
, 24F
07/01 22:39, 24F
→
07/01 22:41,
1年前
, 25F
07/01 22:41, 25F
→
07/01 22:41,
1年前
, 26F
07/01 22:41, 26F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章