結局C++とRustってどっちが良いの? 3traits
■ このスレッドは過去ログ倉庫に格納されています
「C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな」 「うだうだ言ってないで仕事で必要なのをやればいいんだよ、趣味なら好きなのやればいい」 っていう雑談スレ。 前スレ: 結局C++とRustってどっちが良いの? 2traits https://mevius.5ch.net/test/read.cgi/tech/1680363777/ 関連スレ(マ板): Google&MS「バグの70%はC/C++。Rustにする」 https://medaka.5ch.net/test/read.cgi/prog/1619943288/ 板のルールが理解できない、プログラムがロクに書けない人たちのスレ >>1 死んどけ荒らしのクズ あらゆるところに関所がある まるで江戸時代だ 裏山に抜け道を見付けて分け入っても 突然藪から棒に番人が現れる ところがそんな番人も unsafe印籠を魅せれば一撃で退散だ unsafe万歳!!! こんなことなら最初から 表通りでunsafe印籠を出しておけば良かったんだ きっと番人たちも思っているはず さっさと最初からunsafe印籠魅せやがれ 無駄な手間取らせやがって こんなのがエコシステムとか失笑もの === 複製おじさん(通称複おじ)について === Rustスレを中心に活動し、2023年4月現在で1年以上ム板に住み着くRustacean。無自覚な荒らし。 Rustスレでは、基本的に他住民の意見を聞いて糧とすることなく、自らのコードが最善であると、ID変更自演を交えいつまでも主張し続ける。 同スレで「所有権が複製される」という違和感のある表現を、「違和感がある」とする他住民の意見をすべて否定してしつこく擁護し続けたことから、「複製おじさん」というあだ名が付けられた。 それ以外のム板スレでは、基本的に他住民の意見を聞いて糧とすることなく、Rustこそが最善であると、ID変更自演を交えいつまでも主張し続ける。 その基本戦術は、「GC言語は遅い」の一声でC/C++/Rust以外の言語を否定し、残ったC/C++は安全ではないので、Rustが最善であるとするもの。 しかしながら、Rust以外の言語に関しては、正当な批判を展開するのに十分な知識を持っているとは言いがたい。 本スレPart1では、C++の問題点を指摘しようとして多数の誤り・知識不足を露呈することとなった。特にしつこく食い下がったのが「動的ディスパッチ」に関する誤解である。 https://mevius.5ch.net/test/read.cgi/tech/1677286186/786-799 (ID:Evbafc70とID:RiLc+pIfが複製おじさんであると考えられている) 要約すると、通常「条件分岐」と呼ばれるものを「動的ディスパッチ」と呼ぶのが正しいと主張し続けたのである。 常識的にはあり得ない誤解だが、提示されたC++のコードが自らの主張(C++にはパターンマッチが無い)に不都合であると感じたためか、C++のコードを正しく読み解くことができないにもかかわらず脊髄反射的に否定してしまい、その根拠として誤った論理をこじつけてしまったものと思われる。 ちなみにこの後、同種の誤解を持って書き込むID:wHEiYRW7(これはID使用歴的に複製おじさんとは考えにくい)に対して、正しい理解に基づく指摘を行う単発IDが複数出現するが、この中にも複製おじさんが多数含まれていると考えられている。 このように自分の誤りを認識した場合、それを認める書き込みは決して行わず、別人の振りをして最初から正しく理解していた体を装うのも複製おじさんの特徴である。 Fooという型だけを別ファイルfoo.rsへ移してファイルを分けたくなったとする もちろんそれは可能だが二つの方針に分かれる その1 pub mod foo; とする つまり単にmod foo;とするのではなくpubを付けることで利用者がfooにアクセスできるようになる さらにfoo.rsでFooにもpubが付いていれば 利用者はfoo::Fooまたは クレート名::foo::Fooという形で利用できる その2 mod foo; pub use foo::Foo; とする つまりfooは公開しない しかしFooは公開したいのでfooの下ではなくトップでFooを公開する この場もfoo.rsでFooにpubは必要 利用者はfoo::を付けずにFooまたは クレート名::Fooという形で利用できる ようするにファイルを分けたときに 分けた形で公開するならその1 分けたことを隠蔽して公開するならその2 >>5 >自分の誤りを認識した場合、それを認める書き込みは決して行わず、別人の振りをして最初から正しく理解していた体を装う 図らずも昨晩今日のC言語スレでその現象が観測されました さらに型Fooのイテレータだけ別ファイルiter.rsに分けたくなったとする その時はfoo/iter.rsというファイルにする そしてfoo.rsの中でmod iter;とすればよい 分けたことを隠蔽するか公開するか>>6 と同じ方針で望む もし公開するならfoo::iter::Iterのようにパスが長くなる それをメリットかデメリットかで決めればよい 次に>>6 とは全く逆 ファイルを分けたくないけど foo::Fooという形で公開したい時 その場合は pub mod foo { ここにFooの定義など } とすればよい ファイルfoo.rsに分けたときと同じにできる つまり ファイルを分けるか分けないか 公開パスを分けるか分けないか 任意の組み合わせで自由に可能 かの御仁、ディスパッチのことになるとずいぶん熱くなってたよなあ 継承を廃止するのに必要だったからってわけだったみたいね さらに5つ目の方法 ファイルは分けなくて mod foo{...}という形でfooは分けるけど そのfooは見せない! と一見すると矛盾した方針がある その場合は>>6 と>>10 からのご推測の通り mod foo { ここにFooの定義など } pub use foo::Foo; とすればよい 利用者は直接Fooまたはクレート名::Fooとして使える しかしそれならば mod foo{...}を使わずにそのまま直接Fooの定義を書いたのと同じじゃないか! との疑問が湧く ほぼその通りだが この方法によりmod foo{...}の中は名前空間が分離されているため 他とのコードの分離もしっかりできる もし外部との結合があれば mod foo{...}の中で改めてその使用宣言が必要になる 逆に外部から使われるものはpub宣言が必要となる mod foo{...}の中に敢えて入れることでそれら他との関係が明示させられる つまりまとめると3つの自由度がある ・mod fooとして分けるかどうか ・それをfoo.rsとしてファイルに分けるかどうか ・そのfooを外部に見せるか隠蔽するか それらを多段foo::bar::bazそれぞれ含めて自由に決めればよい >>12 Rustは継承を使わずに合成だが 動的ディスパッチ自体はほぼ変わらない vtable部分が合成した各メソッドを含む一覧になる程度 ほとんどのmoduleは 自分の今のprojectから分離して別のcrateに移動しても module内のpub関数はuse cratename;すればそのまま変更無しで参照出来るが module内のmacroはuse cratename;するだけでは参照出来ない #[macro_export] だけでは不十分でmoduleに pub use macroname; を書き足す必要がある >>9 ごめん proc_macro が共存出来なかったって事だった ていうか proc_macro が共存出来ないのは昔からだな ITの世界は短期決戦の世界。知名度がこんなに上がってるのに使用者数が1%未満 のRustには一般言語にまで普及する可能性はほぼ無い。 今までの蓄積ではなく、新しく書かれているコードの量ですら1%未満であることの 意味は、絶対に普及しない路線に入っていると言うことだ。 商品が売れない原因の9割は知名度不足だと言われているが、Rustは既に最高レベル の知名度になった。なのに「売れてない」。それは商品自体に問題があると考え なければならない。俺はRustが嫌いなので、それでいいと思っているが。 結論としてはRustはC++に比べるとファイル分轄が非常にめんどくさいと言うことだな ルールが複雑でめんどくさい 言語仕様なのかcargoの仕様なのかしらないけどフォルダ構造が縛られるし… よくわからんけど自分でstruct沢山作ってcore/modelフォルダ作ってそこに全部突っ込んでフラットに使おうとすると障害があると implをcore/implに突っ込もうとしても問題があると それかそれを参照する何かを別に作らないといけないと 自由度が低い いやーさすがにC++に比べたらRustのが超シンプルなのでわかりやすい C++のモジュール知っててRustのモジュールを理解出来ない人はいないと思う /struct、/impl、/traitみたいな分け方をしたかったのかぁ できなくはないけどやめといたほうがいいんじゃないか したいんじゃなくてそれは仮に書いただけ 自由度が低いと言うことを示したかっただけ ファイル名やフォルダ名が縛られたり なんで自由度が低いのに顔を真っ赤にして自由度が高いと書くのか不明なんだけど 既存のC++のプロジェクトに書き足していくかたちでCargoとかが使われてるんだろ? C/C++の作法に併せたRustのフォルダ構成の裏ルールがあるとしか思えない モジュール名とファイル名(パス)は↓みたいな書き方で一応切り離せるよ ややこしくなるから基本使わないけど #[path="platform/foo_windows.rs"] mod foo; 自由度が高いってのはたぶん外面を維持したまま内装を変更しやすいって意味で使ってたと思う (長文だったからちゃんと読んでない) モジュールの構成は可視性に関わるからそこまで自由ではないと思う 全部にpubつければ自由になるけどそんな自由はいらない 自分が使ってる中ではC#が一番自由度が高い気がする classの分割自由 名前空間の分割自由 プロジェクト内ではフォルダ空間自由 ファイル名自由 global usingと言うものが出来て各ファイルでusingもしなくて良くなった これはいらない機能だと思うけど C#はまじめに使ったことないけど拡張メソッドとかいうのが自由すぎて若干引いた記憶がある どこで何を足されるか分からない恐怖を感じた プロジェクト内のファイル位置も当然自由 一ファイルに複数の名前空間含めるのも自由 Rustがなぜファイル名やフォルダ名でモジュール固定になってるかと言えば それしかモジュール位置を決定する仕組みがないから ルートのコードからたどれる物しか名前を解決できないから それが良くないんじゃないの? >>35 既存のクラスすべてで必ず拡張されるわけじゃない 本当は拡張などしてなくてただのstaticメソッドだし どこかそれを他で使われていてもそれをusingしなければ使えないから関係ない usingしててもpublicじゃなければ見えないので影響はない proc_macro で黒魔術やりたい放題出来る様になりますた おまいらのお蔭です本当にありがとうございますた っていうか proc_macro::TokenStream と proc_macro2::TokenStream と 同時に使うと違うと判ってても混乱するな >>35 >どこで何を足されるか分からない恐怖を感じた これは Rust の trait や後付けの impl にも同じ臭いを感じる 一応Rustのimplは型(trait)を定義したクレート内に制限かけてるけどそれでも気になる人はいるか 自由な場所で定義を足せるとどうしても散らかりやすくなる >>38 ---- lib.rs 側 ---- use proc_macro::TokenStream; use proc_macro2::TokenStream as PM2TS; (略) #[proc_macro] pub fn mk_ts(_item: TokenStream) -> TokenStream { let mut ts: PM2TS = PM2TS::new(); Ident::new("let", Span::call_site()).to_tokens(&mut ts); Ident::new("x", Span::call_site()).to_tokens(&mut ts); Punct::new('=', Spacing::Alone).to_tokens(&mut ts); Literal::u8_suffixed(255u8).to_tokens(&mut ts); Punct::new(';', Spacing::Alone).to_tokens(&mut ts); ts.into() } ---- main.rs 側 ---- fn main() { mk_ts(); println!("{}", x); } これで実行は出来たけど TokenStream がぶつかってるのが気に入らない main.rs の方は mk_ts!(); だった >>30 基本的に、JavaとC++は兄弟言語で、共通点がとても多い。 classの概念もほとんど同じだし、とても良く似ている。 一方、RustとC++は全く違う言語。 全く違うんだが 現状は C からの置換を目指さなきゃいけない その辺りが フォルダ構成にも反映されてしまっている 当然だが マッチの箇所は プロログなどの方が近い 現にデコンストラクトによるパターンマッチはlispかhaskelくらいでしか見かけない 似てたら置き換えやすいけど、置き換える意味も薄まりそうだけどな 「みんなが使ってないものが使いたい」という心理を持っている人が一定数いて、 Rustはそういう人に受けてる可能性もある。 Microsoft「Windows 11がまもなくカーネル内でRustを用いて起動」 https://www.neowin.net/news/senior-microsoft-exec-says-windows-11-kernel-will-soon-be-booting-with-rust-inside/ BlueHat IL 2023 カンファレンスにおいて、マイクロソフトのエンタープライズおよび OS セキュリティ担当バイス プレジデントである David Weston が登壇し、 Windows セキュリティの進化について話し合い、最新の進歩と今後の道のりについての洞察を講演しました。 プレゼンテーションの中でWeston氏は、MicrosoftがWindowsカーネルの一部としてRustを使用して行ってきた進歩について説明しました。 いくつかの理由でこの言語に興味を持っており、そのうちの11つはRustが提供するメモリの安全性とセキュリティを中心にしています。 Weston氏は次のように述べています。 「おそらく今後数週間または数か月以内に、カーネルでRustを使用してWindowsが実際に起動することになりますが、これは本当にクールです。 ここでの基本的な目標は、これらの内部C ++データ型のいくつかをRustの同等のデータ型に変換することでした。」 前スレにも書いたけど、ブートローダってDOSアプリみたいなもんで、劇的に画期的じゃないんだよ APIが早くRust化してほしい そうすれば、C++も恩恵を受ける マイクロソフトがわざわざC++を捨ててまでRustを採用するとはよっぽどのことだよな Linuxの方は元からC++さえ排除してC言語だけの純血主義だったのにRustを採用し始めてる >>49 記事を読んだがブートローダーなんて書かれてなかった Rustを使った場合のWindows OSのパフォーマンス比較でOffice apps使用の場合が出てくるからブートローダーの話ではないね 昔、マイクロソフトはわざわざJAVAを捨ててJ++を開発したんだよなあ これまで多数の言語が登場したけど求められてる条件はたった二つだけ 「C/C++と同等のパフォーマンスが出ること」 「C/C++の各種安全性の問題が解決されていること」 Rustが最初で唯一の言語 >>53 安全にするにはGC言語にするしかないと思われていたからね Rustだけが勝者となった Rust以外でGC採用せずにメモリやリソースの後始末をちゃんとしてくれるよう設計された言語って何があるの? お! GC君だ(この人が複製おじさん?) GC君は他人のことを初心者呼ばわりするけど 技術的な話が全くできないんだよなぁ... >>50 $ tar xJf linux-6.3.1.tar.xz $ find linux-6.3.1 -name *.c -o -name *.h | wc -l 55806 $ find linux-6.3.1 -name *.rs | wc -l 38 0.07%未満! 前回v6.2.1のとき37だったから1ファイルは増えてるね 何が増えたかは $ diff -uNr <(cd linux-6.2.1; find . -name *.rs) <(cd linux-6.3.1; find . -name *.rs) >>52 JavaScriptをわざわざパクッてJscriptってのも作ったな 今やIEブラウザごと滅んだが アップルとかソニーとか独自規格を作りたがる連中はいつの時代も迷惑 Rustはメモリリークには割と寛容なんだよね 野生の参照(ダングリングポインタ)は目の敵にするけど >>56 Rustしか現存しない 他に出てきそうにないため今後Rustの時代が続くのだろう >>45 >デコンストラクトによるパターンマッチ 聞かない用語ですねぇ~ デコンストラクト >>60 ヒモさえ付いてれば無駄遣いしてもOKみたいな RustってNimに対して何か優位なところはあるの? >>63 NimはGC言語 GCに頼らず済ませられる部分のみ使わないで済むというだけ >>56 間違い:メモリやリソースの後始末をちゃんとしてくれる 正解:メモリやリソースの後始末をちゃんとしてくれる(リーク除く) 基本GCでも充分な性能が出れば別にいいよ 最適化が必要なところだけ手動でやるのはRustも同じだから 手動ライフタイム管理とのトレードオフ >>69 RustはNimのような逃げをしていない点で全く異なるよね NimはGC言語という点でも誰も異論はなく FactorはForthとLispの子みたいな動的型付け言語 ガベージコレクションあり GCの有無は指標になるけど、現状のC++の、なんでもかんでもヒープに置く習慣は、 GCとそんなかわらないんじゃ…と思わなくもなかったり C++はコンパクションが行えないので、GC付きのJavaのほうが速いのです って言ってなかった? 感覚的にはプリミティブでない単純なデータ(xyz座標とか)の配列を直接作れるかどうかがボーダーな気がする ポインタの配列を作ってるようだとGCしなくてもGC言語 C#は微妙なライン 変なタイミングで大掃除始める問題もあるけどこっちを気にする機会は少ないような 結局、RustはC++より速くても、Javaよりは遅いってことですね もう少し待てはマイクロソフトがR++を出すと思うから それまで待って >>76 Rustはスタックを多用する言語なのでJavaより速い >>80 スタック上のメモリ領域はCPUレジスタであるスタックポインタを足し算引き算するだけでメモリ確保と解放できるため最も速い >>81 CPUの仕組みを知っててそういう認識の人はいないと思いますよ >>81 のスタックメモリ利用が一番速いで合ってるけど スタックメモリは関数から戻ると自動的に開放されその部分は無効になっちゃう そのため従来の言語ではスタックメモリの利用を抑え気味にすることでその問題を過剰に回避してた Rustはライフタイムの導入でスタックメモリを安全な範囲内の限界まで使えるようになったことが違いかな CPUのレジスタ利用が一番速いがレジスタ割り付けの最適化が非常に難しいので スタックを使ってお茶を濁してる スタックメモリが主記憶と別の場所にあると思ってない? もしかしてヒープは主記憶、スタックはプロセッサの中にあるとか思ってない? いま検索中? メモリの確保の仕方の違いでの速さの比較の話でレジスタの話を持ち出すのは違うでしょ そしてレジスタの数は限界がありその退避先もスタックメモリですよ スタックメモリに割り当てられた変数は最適化によりレジスタ割り当てが可能であればレジスタのみ利用になりますね >>86 スタックメモリは単なるメインメインの一部にすぎません しかしメモリ確保と解放が最も速いだけでなくメモリキャッシュに載る点でアクセスも速いです 頭のおかしい人間がずっと一般的な事実に基づかない頓珍漢な独自妄想理論を展開してる スタックを積極的に利用しているからrustがjavaより速いと言われて 納得する馬鹿はいないだろ もっと根本的な理由があるだろと javaはVMでスタックマシンをエミュレートしてるから遅い 通常はレジスタ一発で出来ることもわざわざスタックマシンでエミュレートしてるので遅い スタックメモリが確保の点でもキャッシュされてる点でも非常に速いのは常識 そのためGC言語であってもGoのようにまずはスタックメモリ利用を優先する (他へ渡すときだけGC対象になるヒープを利用) >>95 Rustはそこからさらに一歩進めて他へ渡すときもスタックメモリを使えるように改善してますね Rustはライフタイムの導入でスタックメモリを安全な範囲内の限界まで使えるようになりました 変な人大集合だね それがrustよりjavaが速い理由だと思い込んで疑わない変な人たち おっと逆だ それがjavaよりrustが速い理由だと思い込んで疑わない変な人たち ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる