結局C++とRustってどっちが良いの? 2traits

■ このスレッドは過去ログ倉庫に格納されています
2023/04/02(日) 00:42:57.53ID:W9/nq+tL
「C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな」
「うだうだ言ってないで仕事で必要なのをやればいいんだよ、趣味なら好きなのやればいい」

っていうスレ。

前スレ: 結局C++とRustってどっちが良いの?
https://mevius.5ch.net/test/read.cgi/tech/1677286186/
2023/04/19(水) 10:35:26.97ID:4c9fSoSa
> 初心者が間違えて踏んでしまうことは決してなく

ここだねえ 穴があったら、落ちるもんなんだよ

そこんとこは、コピペ勢に証明してもらうとするわ
俺が気に入らないのはコピペ勢だ、あいつら俺の母語を侮辱するからね
2023/04/19(水) 11:03:31.64ID:Y2fuF+9L
現状追認主義ここに極まれり
もはや信者以外の何者でもない
2023/04/19(水) 11:04:59.07ID:mEvWDtbQ
ソースコードで示してって言うと
理解しないままの受け売りなのですぐにボロが出る
ChatGPTの流行をマジで危惧してるよ
2023/04/19(水) 11:57:16.55ID:01eJvfIU
>>266
初心者が誤ってunsafe宣言するかな?
2023/04/19(水) 12:07:36.70ID:4c9fSoSa
そうじゃないけど、それもあるな
ちゃんと規制しないと、unsafe 使いまくられたら一緒じゃんwwって反論もできるな
2023/04/19(水) 14:59:19.03ID:4c9fSoSa
思わぬところに反論しときたいんだが

>>265
> 何度も何度も何度もプロたちがミスってきた

ここはちょっと要検証じゃね たとえば、Chromium/Chromeは精鋭だけで書かれたのか
ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、静的解析に通るように綺麗に書く
だから、「馬鹿にするな、C++が悪いんじゃない、悪い奴が悪いんだ」って反論も出る

C++はプロじゃない人間も使う、例えば俺 だから、C++にもunsafe{ } が必要なんだ

些細なようだが、ちゃんとしてるプロをバカにすることはない
敬意を払うのは人の為ならず(自分のため)
2023/04/19(水) 16:01:07.64ID:mEvWDtbQ
>>271
>ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、
使いこなすって表現するほどスマートポインタは御大層なものではない
そもそもmake_uniquやmake_sharedするのは
俺の場合は全インスタンスの1割弱だよ(newは一切無い)
operator newを呼ばずにインスタンスを作るのが9割超
2023/04/19(水) 16:53:43.84ID:ZJsXKDj1
>>264
>C++だって、「そんな書き方すんなよ」ってのを踏むヤツが後を絶たない

これな
前にも誰か言ってたが vector にぶっこんだデータを参照するときに
再配置が起きると参照先が無くなって困るとか
そりゃ再配置が起きるような書き方してる方が悪いんだよ
2023/04/19(水) 18:49:07.48ID:s8p2Q+oA
よくわからんが、プログラマーはlifetimeのパラメーターを明示的に実体化できないんだよね
人間の代わりにコンパイラが暗黙に自動的に実体化する
なんで人間が何か踏んだとか人間が穴に落ちたみたいに言われてるんだ?
2023/04/19(水) 19:51:56.67ID:ckDmN3Ij
コンパイラが調整する余白部分はあるけど包含関係を明示する程度にはプログラマが指定できる

ライフタイムは
「関数内のローカル変数の参照を関数の外にreturnしても受け取った側では使えなくなってる」
みたいなC++でも一般的なルールを概念的に表してるだけだよ
関数じゃなくブロック単位でスタックを伸縮させるコード生成があるかは知らないけど
ライフタイムはスタックのどの辺にそのデータ(の根拠)が置かれているかにおよそ対応してて
スタックの先端の方ほどライフタイムは短くなるし根元に近いほどライフタイムは長くなる

参照値の場所より根元の方を参照する分にはとりあえず安全だけど参照値より先端の方を参照してると
知らないうちに処理が進んでスタックが短縮されて参照先が無効になるかもしれない
そういう参照エラーをコンパイラで排除するためにライフタイムが使われてる
参照先は参照元より根元に近い(長生きする)ことが保証されてる範囲でしか認めない感じかな

実際は参照値もデータもスタック上で引っ越したりするし
被参照中はそのデータが動かせなくなるみたいな別のルールもあるからややこしいけど
2023/04/20(木) 00:49:58.65ID:9yNISOE6
Rustについて教えてちょ
以下はsizeが実行時に与えられるので
vについてアクセス違反を起こしていないかコンパイル時には
チェックできないと思うのだけどRustで書くとどうなるのかな?
#include <iostream>
#include <vector>
using namespace std;
int main () {
vector <int> v {1, 2, 3};
size_t size;
cin >> size;
if (v.size () < size)
{
cerr << "The specified number must be less than or equal to " << v.size () << ".\n";
return -1;
}
for (size_t i {0}; i < size; ++ i)
cout << v [i] << '\n';
return 0;
}
2023/04/20(木) 00:51:46.92ID:iAIcEMT7
そ、そんなに言うんだったら、お、俺もRust始めてみるよ
278デフォルトの名無しさん
垢版 |
2023/04/20(木) 01:16:01.15ID:GPVFd3S9
>>276
Rustは基本bound checkがされるからそれっぽいコードだと実行時にパニックで落ちる

bound checkも避けて落ちないようにするならイテレータをtake(size)する
279デフォルトの名無しさん
垢版 |
2023/04/20(木) 01:19:28.98ID:GPVFd3S9
他言語なら0..min(v.len(), size)とかもあるだろうけどRustではあんまりやらないと思う
2023/04/20(木) 01:22:50.03ID:9yNISOE6
Rustにはindexでアクセスするコンテナってやっぱないのかな?
2023/04/20(木) 01:24:33.22ID:9yNISOE6
>>278
>Rustは基本bound checkがされるからそれっぽいコードだと実行時にパニックで落ちる
あれ!? ということはコンパイルは通るの?
2023/04/20(木) 01:42:12.31ID:px2D1mrK
Rustでは普通こう書く
for n in v.iter().take(input_size) {
println!("{n}");
}

どうしてもインデックスでアクセスしたいなら
他の言語と同じく小さい方まで回す
let ok_size = min(v.len(), input_size);
for i in 0..ok_size {
let n = v[i];
println!("{n}");
}
2023/04/20(木) 01:54:59.31ID:px2D1mrK
あとはインデックスを使いminを使わないならばこうかな
for i in (0..v.len()).take_while(|&i| i < input_size) {
let n = v[i];
println!("n={n}");
}

3つとも同じ動作となるけど
簡潔かつインデックス不要な最初の方法がRustでは普通
2023/04/20(木) 01:56:51.02ID:9yNISOE6
>>282
ありがとう
最初のはinput_sizeがvの要素数よりデカかったらどうなるの?
2023/04/20(木) 01:59:04.25ID:9yNISOE6
>>282,283
3つともunsafeで囲まなくてもコンパイルは通るのでしょうか?
2023/04/20(木) 02:22:14.41ID:px2D1mrK
>>284
イテレータのtake(n)は最大n個になる
その前のv.iter()からv.len()個の参照が来る
だからnがv.len()より多くてもそれ以上ポインタは進まず安全

>>285
unsafeは必要ない
自分ですぐ試せるからここで何でもやってみればいい
https://play.rust-lang.org/
Rustで普通に使っていてunsafeは出て来ない

unsafeが出てくるのは例えば
FFIでC言語など別言語からの変換とか
既存ライブラリにない新たな仕組みの型を作り出すときに
unsafeを使わざるを得なくてunsafeを閉じ込めて安全なインタフェースを提供する場合
2023/04/20(木) 02:38:45.55ID:9yNISOE6
>>283
(0..v.len())でインデックスを作ってると思うのだけど
コンパイラはfor節の中でアクセスされるvのサイズと
インデックスの最大値の比較まで行ってるってことかぁ
2023/04/20(木) 02:54:57.60ID:px2D1mrK
>>287
例えば 0..10 は0から10未満つまり0から9までの数値を返すイテレータ
インデックスかどうかは関係ないし配列やVecとも無関係
非負数値だからたまたまインデックスとしても使えるというだけ

いずれにせよ配列やVecのシーケンシャルアクセスにインデックスを使うのは無駄なので
インデックスは使わずに>>282の前者を使おう
2023/04/20(木) 03:11:11.34ID:9yNISOE6
ボローチェッカの挙動を知りたいのだよ
以下だとコンパイルは通らないんだよね?

for i in (0..100).take_while(|&i| i < input_size) {
let n = v[i];
println!("n={n}");
}
2023/04/20(木) 05:14:11.17ID:px2D1mrK
コンパイルも通る
そこには借用(ボロー)つまり参照がないからボローチェッカーは無関係
厳密にはtake_whieは参照を取るが対象が整数値なのでコピーして比較していて無関係
let n = v[i]; も整数値のコピーなので無関係

ちなみにC以外ほとんどの言語と同様に v[i] は安全にインデックス範囲チェックが行われる
範囲チェックの結果を受け取りたいならばget()によりOptionを得ることもできる
例えばこれで安全にアクセスできる
if let Some(n) = v.get(i) {
println!("n={n}");
}

シーケンシャルアクセスならインデックスによるアクセスの必要性がないので
v.iter()を使い安全に各要素の参照を得ることができる
したがって>>282の前者が簡潔で可読性もよく安全で高速なRustでの普通の書き方
2023/04/20(木) 09:48:13.23ID:9yNISOE6
>>290
なるほど

>ちなみにC以外ほとんどの言語と同様に v[i] は安全にインデックス範囲チェックが行われる
C++でいうと以下のような感じなのかな?

for (size_t i {0}; i < input_size; ++ i)
cout << v.at (i) << '\n';

Rustはメモリアクセス違反を何でもかんでもコンパイルで弾けるわけじゃないのね
2023/04/20(木) 11:20:58.88ID:ViRjvm8y
アクセス違反が発生しても何となく動き続けることがなければとりあえずセーフの精神
unsafe内でuncheckにするオプションも用意されてることが多いけど
2023/04/20(木) 11:29:56.72ID:vzrku2iH
DoSにつながるから、落ちるのはよくないみたいに言われたりするんだけど、
変に無理に動き続けるより、異常を見つけたら落としたほうがいいときってあると思うんだよな
落ちるバグはコールスタック残ってればいち早く潰すだろうし
294デフォルトの名無しさん
垢版 |
2023/04/20(木) 11:44:16.22ID:GPVFd3S9
バッファオーバーフローみたいな脆弱性につながるから落とすほうが安全なんだよ
2023/04/20(木) 11:48:21.96ID:SYxH5KMK
C/C++とは異なり、Rustは範囲外メモリアクセスを絶対に起こさないことが保証される点が決定的な違い
シーケンシャルアクセスでは、Rustではv.iter()とイテレータを使い、結果的に終端アドレスに達するまでポインタが進むのと同じ生成コードになるので、最高速かつ安全に範囲内のみのコードになる
そのうえで、v.iter().take(input_size)など様々な条件や加工などをするイテレータメソッドを複数組み合わせて、メソッドチェーンにより簡潔な記述をするのがRustでの書き方
2023/04/20(木) 13:05:49.56ID:9yNISOE6
>>295
ディフェンスラインが後退したな
STLのコンテナもatでアクセスすれば範囲外アクセスで例外を投げるので同じ
オーバーヘッドが気になるならoperator[]によるアクセスも
イテレータによるアクセスも選択できる
2023/04/20(木) 13:34:13.29ID:w/28tNmU
C/C++はポインタと配列の区別があやふやだ

まず配列という概念がない言語でポインタの問題だけを解決し
それから配列をたんなるライブラリとして追加するほうが無駄なトラブルが少ない
配列すらない状態に一旦後退するのは正しい

その意味では、ジェネリクスがない状態に後退できるC/C++を見習うべきだったとも言える
2023/04/20(木) 18:25:05.04ID:zqUq/1wh
>>296
違いはここ
・安全な言語: 範囲外アクセスをすることが絶対にない
・安全でない言語: 範囲外アクセスをしてしまう
CとC++は不合格
2023/04/20(木) 19:53:34.14ID:9yNISOE6
>>298
範囲外かどうかチェックのオーバーヘッドがあるのではないのかな?
C++はチェックありもなしも選択できるんだよ
2023/04/20(木) 20:48:09.87ID:D1KovJeq
Rustもインデックス範囲内チェックの有り無しを選べる
基本的にはインデックスは使われず、安全な範囲内に動くポインタのみを、自在に各種イテレータメソッドで扱うため、オーバーヘッドはゼロ
唯一の例外が真のランダムアクセスで、範囲内のインデックス値か不明なものを扱うため、インデックス毎に範囲内チェックは絶対に不可避なためコストがかかる
その場合でも、範囲内のインデックス値しか来ない構造ならば、新たな型をunsafeなget_unchecked()を用いてそれを閉じ込めて、安全なインターフェースとして提供できるため、オーバーヘッドはゼロ
2023/04/20(木) 21:12:04.09ID:8LRk4zHW
>>300
それC++と何が違うのかな?
302デフォルトの名無しさん
垢版 |
2023/04/20(木) 21:17:13.53ID:B6QJskar
チェックを忘れて脆弱性を埋め込むリスクが桁違い
2023/04/20(木) 21:33:10.92ID:9yNISOE6
>>302
すまんが何が違うかを書いてくれないかな?
あるいは>>300が何を言わんとしているか
他の人の解説でもいいんだけど
2023/04/20(木) 21:38:15.36ID:iAIcEMT7
>その場合でも、範囲内のインデックス値しか来ない構造ならば
この判断を誤ると結局脆弱性が埋め込まれそうだけど、
チェックを忘れることに比べれば起こりにくいのかもね
2023/04/20(木) 21:40:24.96ID:SYxH5KMK
>>301
オーバーヘッドに関してはC++もRustも最小限にすることができて同じ
安全性に関しては範囲外アクセスが生じうるC++のみ安全でない
2023/04/20(木) 21:40:47.43ID:9yNISOE6
私は違いがサッパリ分からんぞ
2023/04/20(木) 21:44:22.16ID:9yNISOE6
>>305
>安全性に関しては範囲外アクセスが生じうるC++のみ安全でない
範囲外チェックなしでインデックスでアクセスしたら
Rustも危険なのでは?
2023/04/20(木) 21:51:17.50ID:D1KovJeq
>>304 >>307
その場合は、一般的にunsafeを閉じ込めてsafeなインタフェースを提供する新たな型をモジュールとして提供する
そのモジュール部分のみを人間が安全性を保証する形になり、その利用者側はRustコンパイラが安全性を保証する
したがってそれを利用する側のプログラマーのミスで範囲外アクセスなどが起きることはない
2023/04/20(木) 21:56:16.00ID:9yNISOE6
>>308
今はそのunsafeに閉じ込める部分に
C++とRustで差があるのか無いのかを議論している
お分かりかな?
2023/04/20(木) 22:01:05.35ID:9yNISOE6
>>307
私はせっかちなので自分で議論を進めると(と言っても私はRustは分からんのだが)
範囲外チェックなしでインデックスでアクセスできる -> Rustも同様に危険
範囲外チェックなしでインデックスでアクセスできない -> Rustはオーバヘッドがある
ということになる
311デフォルトの名無しさん
垢版 |
2023/04/20(木) 22:03:11.36ID:cejxbewD
複オジの説明がクソだから伝わらなくても仕方ない
2023/04/20(木) 22:06:37.25ID:9yNISOE6
>>295
>C/C++とは異なり、Rustは範囲外メモリアクセスを絶対に起こさないことが保証される点が決定的な違い
によると後者ってことになるが

>>300
>Rustもインデックス範囲内チェックの有り無しを選べる
によると前者ってことになる

矛盾しとる
どっちや?
2023/04/20(木) 22:18:01.10ID:FIsyFWOj
C++に勝ってると主張するために普段はunsafeのことを脇に置いてメリットばっかり語ってるのに
性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出すからややこしいことになるんじゃな
2023/04/20(木) 22:26:58.01ID:dJqrvGvM
昔LISPもそれでCと張り合ってたな
歴史は繰り返すんやな
2023/04/20(木) 22:36:42.26ID:98y/hYCF
話は簡単
RustはVecもそこで使われるスライスのイテレータも
unsafeなコードを閉じ込めてsafeなメソッドを提供している
だからその部分の作成は人間がミスるとおしまい
逆に言えばその狭い範囲のみ人間が頑張って安全性を保証すればよい

一方でそれらVecやイテレータなどを利用する一般のプログラマーは
そのsafeなメソッドを使っている限り絶対に安全なことが保証される
もし問題があればコンパイラがエラーを出すので常に安全となる

結論
RustもC++も最小限のオーバーヘッドが可能で同じ
しかしその安全性は全く異なる
C++は常にミスったらおしまい
C++はプログラム全体に対して人間が安全性を保証しなければならない
Rustはsafe利用者がミスることは絶対になくコンパイラがエラーを出してくれる
Rustはunsafe利用部分のみ人間が安全性を保証しなければならない
2023/04/20(木) 22:42:39.55ID:9yNISOE6
>>315
一生懸命書いているところを申し訳ないが
>>276の話で始めたように今は
コンパイル時にチェックできない状況の話をしているんだ
2023/04/20(木) 22:43:11.74ID:98y/hYCF
>>313
そのunsafeなget_uncheckedの件も同じ
unsafeを利用してsafeを提供する人だけがその安全性の保証できるコードを書けばよい
一方でそこで作られたsafeなものを利用する一般プログラマーはミスってもコンパイラがエラーとして止めてくれる
2023/04/20(木) 22:44:27.28ID:9yNISOE6
>>98y/hYCF
>>312はどっちや?
2023/04/20(木) 22:44:35.26ID:98y/hYCF
>>316
Rustではコンパイル時に安全性を必ずチェックできる
2023/04/20(木) 22:48:29.32ID:9yNISOE6
>>319
実行時にサイズを入力するのにかい?
Rustコンパイラは未来が分かるのかw
2023/04/20(木) 22:49:34.33ID:98y/hYCF
>>318
どちらも正しい
効率的なunsafeを使いそれを閉じ込めることで効率的なsafeを提供することがRustの基本
一般プログラマーはそのsafeのみ使えば書いたコードの安全性が保証される
2023/04/20(木) 22:55:08.59ID:98y/hYCF
>>320
最初に出ているこのコードのことだろ
for n in v.iter().take(input_size) {
println!("{n}");
}
もちろんinput_sizeの値に関わらず静的に安全なコードだ
そしてインデックスは用いないのでインデックス範囲外チェックは無い
Cでポインタで書いたときと同じ速度になる
2023/04/20(木) 22:56:41.18ID:9yNISOE6
議論にならんのでスルーして
彼の主張は(正しいのかは分からんが)
要するに範囲外チェックなしでインデックスでアクセスできるということだから
Rustも同様にこの点は危険ということになる
2023/04/20(木) 23:00:30.54ID:9yNISOE6
>>322
今はRustでも危険に書けるでしょ?って話をしている
イテレータを使えば安全なのでこう書くべしっていうのなら
それはC++となんら変わらない
2023/04/20(木) 23:23:11.63ID:SYxH5KMK
>>323
Rustはチェックしないけど安全な型を作れるよ
例は何でもいいんだけど例えば将棋盤を表す型を9✕9=81のインデックスを考えてみよう
その将棋盤の型に対するインデックスの型を新たに作ってメソッドとその操作を限定することでusize化した時に常に0~80の値しか取らない型を作る
あとは unsafeを使ってsafeかつ効率的な実装
impl std::ops::Index<将棋盤インデックス型> for 将棋盤 {
type Output = 将棋駒;
fn index(&self, index: 将棋盤インデックス型) {
unsafe { self.0. get_unchecked(index.to_usize()) }
}
}
これで将棋盤型のアクセス時にインデックスの範囲内チェックは行われずに効率的かつ安全
(将棋盤インデックス型の定義によりindex.to_usize()は常に0~80の値のみをとるため)

将棋の実装を実際にしたことはないが
似たようなデータ型は実際に何度か書いたことがある
2023/04/20(木) 23:29:13.60ID:vzrku2iH
C/C++にも、-fsanitize=address ってのが後追いながらちゃんと入ってきてる
その価値は認めていいし、しかし、差は縮まりつつある
2023/04/20(木) 23:32:10.47ID:vzrku2iH
Rustでも、unsafe が抜け穴になるよね、って反論はつまり、
コピペ勢に対して、「いやみんなばんばんunsafe使っちゃうからダウト」って返してるってことw

ここにたまるようなヤツは、必要に応じてモジュール毎にON/OFFくらいできるヤツ
熱心に張り合うまでもなく、有意義に使うよ
2023/04/20(木) 23:56:26.81ID:98y/hYCF
わずかなunsafe封じ込め部分だけに注力することで、効率的なsafeを作ってしまえば、safe利用者はコンパイラに安全性の保証を任せられることがRustの最大のメリット
2023/04/21(金) 00:05:38.80ID:SijbBkLt
わずかになってくれればいいね

ああ、また釣られてしまったw
2023/04/21(金) 00:13:14.15ID:4oRlgId+
>>325
安全にも書けるのは分かる(それはC++も同じこと)
9yNISOE6の主張が正しいと仮定して
Vecのアクセス範囲に関して危険にも書けるけど
Rustコンパイラは何もできないよねって話
2023/04/21(金) 00:14:20.12ID:4oRlgId+
まちごうた
-9yNISOE6の主張が正しいと仮定して
+98y/hYCFの主張が正しいと仮定して
2023/04/21(金) 00:14:28.54ID:7fROJFuD
最適化はunsafeというのはRustではほぼ客観的事実に近い

C++で似たような意見を言えば、最適化の足を引っ張る陰謀と見分けがつかない者もいるだろう
2023/04/21(金) 00:19:35.15ID:9IEMPFWw
範囲がconst/constexprであれば、チェックコストはゼロにしうるのでは
そこにコストをかけてでもsafeにしましょうというのがモダン(含Rust)
そこにコストがかからないように書いてナンボなのがC++(失敗時は: 安全だがコストが生じる)
2023/04/21(金) 00:58:19.29ID:9IEMPFWw
関係あると思うのできかせて

いまさら人に聞けないんだが、Intel MPXってのが早々にディスコンになったのは、
・MPXでも抜けがあることがわかった
・いまやパイプライン? が優秀すぎて、MPXでもソフトウェア サニタイザでもそんな変わらなかった
っていう理解をしてるけど合ってる?
2023/04/21(金) 01:08:57.82ID:mE/p3bqb
英語版wikiだと穴が多すぎて実用に耐えなかったって書いてるな
日本語版はなかった
https://en.wikipedia.org/wiki/Intel_MPX
2023/04/21(金) 02:33:15.05ID:9IEMPFWw
かのIntel(当時)が頑張ってもこんなもん(こんなことになる)か
難しいもんなんだな。。

俺にできないだけで、本気出せば難しくないもんかと思ってたのに
2023/04/21(金) 05:31:12.23ID:7fROJFuD
具体的に誰が頑張ったのか全然わからない
いまさら英雄化してももう遅い
338デフォルトの名無しさん
垢版 |
2023/04/21(金) 09:34:15.68ID:Jt0l0JSP
>>330
>安全にも書けるのは分かる(それはC++も同じこと)
C++でもRustと同じレベルで安全に書けるというのはさすがにウソでしょ
複オジの説明がショボいからと言ってウソはダメだよ
2023/04/21(金) 10:24:01.60ID:YWjwap1N
play.rust-lang.org で
use rstk::*; とか
use wx; とか
もちろん出来ない訳だが
use したときに一瞬一覧で選べるものが出て来るので
これの一覧をテキストファイルで欲しいんだが
どこで観れますか?
2023/04/21(金) 10:33:13.77ID:YWjwap1N
>C++に勝ってると主張するために普段はunsafeのことを脇に置いてメリットばっかり語ってるのに
>性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出す

ほんそれ
341デフォルトの名無しさん
垢版 |
2023/04/21(金) 11:32:23.34ID:obBiE3Vg
>>339
crates.ioのダウンロードTop100とその依存クレート
入れ替えとかどう対処してるのかは知らん
playgroundのヘルプにリスト(Cargo.toml)へのリンクがある
2023/04/21(金) 15:41:39.16ID:YWjwap1N
>>341
thx!
自分用のCargo.tomlに置き換えたいときは?
343デフォルトの名無しさん
垢版 |
2023/04/21(金) 16:08:14.43ID:e/N20Lgf
>>342
それは自分の環境でどうぞ
344デフォルトの名無しさん
垢版 |
2023/04/21(金) 21:37:21.45ID:AfLtEamq
控えめに言って Rust は超マゾ言語
2023/04/21(金) 23:59:16.40ID:LZBHeARm
C++もRustも基本的には変わらん
C++で常に安全に書ける人にとってライフタイムなんてすぐ理解できて困らん普通のことだった
Rustでいいと思ったのはイテレータメソッドチェーンのシンプルさとか
あらゆる部分でパターンマッチングできる点とか
2023/04/22(土) 00:04:17.51ID:L3G+XloM
GC言語は良いと思うし使いけど可視化する気にならない
GC言語が多過ぎるから
Python並みの人気でも過半数に支持されるとは思えない
2023/04/22(土) 01:08:10.55ID:6MRD/fZf
ライフタイム付き再帰構造体を再帰関数で回してlifetimeのvarianceで苦しむまでがボローチェッカチュートリアルです
2023/04/22(土) 05:11:35.36ID:ve/ll5uR
Rustの弱点突きまくり
2023/04/22(土) 07:15:46.36ID:iD47eBZH
言語(Rust含む)がせっかく親切にしてくれてるのに、その虚を突く

…っていうか、虚を天然で踏み抜いちゃうのが、シロウトなんだよなあ 俺含む(自戒
350デフォルトの名無しさん
垢版 |
2023/04/22(土) 07:19:16.96ID:UYc1nlSd
PythonのAI系のライブラリを
rustで作り直したら爆速になるのかな?
2023/04/22(土) 07:23:17.49ID:iD47eBZH
大人気のCUDA版は、CUDAでできてるから Pythonで操ってるだけ
352デフォルトの名無しさん
垢版 |
2023/04/22(土) 09:44:15.55ID:UBHQks3G
C++のライフタイムが本当に簡単ならライフタイム系のバグを100%検知できるツールなんて簡単に作れるはずだよね?
2023/04/22(土) 09:50:17.61ID:OMpDwvP8
>>352
そういう意味ではなく逆だろ
C++でもともなコードを書けているプログラマーはRustでライフタイムをすぐ習得してしまう話だろう
逆にライフタイムを難しいと言ってるプログラマーはC++で込み入ってくると正しいコードを書けない
2023/04/22(土) 10:40:59.94ID:iD47eBZH
>>352
いくらか指針・実装はあったんだけど、決定打に欠いた
いろいろと自由すぎたんだよ

Rustのやり方が業界標準になったら、C++がそれを取り込むのは早いと思う
2023/04/22(土) 10:48:04.53ID:/en2DlgL
varianceをOOPにたとえると
変数の型を宣言できないが基底クラスなら宣言できる
という理解でいいんでしょ
変数の型を宣言するツールを簡単に作れるかが問題なのでは
356デフォルトの名無しさん
垢版 |
2023/04/22(土) 10:54:03.92ID:8hXabeY8
ポインタと同じでライフタイムも概念を理解するのは何も難しいことはない
バグなしで使いこなすのが難しいだけ
それだからRustは厳しめのルールにしてコンパイラでチェックする
C++が脆弱性を量産してきた負の遺産を継承しないためにね
2023/04/22(土) 11:23:28.94ID:XW9UuYWq
>>356
所有権システムは単純に使いづらい
インスタンス作るときのデフォルトにされるのはちょっと...
2023/04/22(土) 12:09:24.25ID:SKSgk+MB
少し前にvectorの再配置の例が出てたけど
他で参照してる間にデータを操作して参照がおかしくなる事故が後を絶たないから仕方ない
普通のイテレータで走査してる最中に要素を削除したりとか
2023/04/22(土) 12:57:45.65ID:/en2DlgL
>>358
参照カウントが2以上ならエラーでいい
実行時エラーなら難しくない
コンパイル時が難しいだけ
2023/04/22(土) 13:13:05.95ID:XW9UuYWq
>>358
それはどういう状況かな?
2023/04/22(土) 13:44:44.50ID:3JkCsMe2
RustはまだMicrosoftがVisualRust出してないしなあ…
2023/04/22(土) 15:25:53.88ID:V6k8LZu5
Microsoft方言なRustとかはいらん
2023/04/22(土) 15:57:35.73ID:nX3yaBf6
>>357
所有権システムはC++もRustも基本的に同じで難しいところはない
表記方法は両者で異なるがRustの方がシンプルに整理されていてわかりやすいだろう

そのインスタンスの挙動についてもRustは新たな型宣言時に特に指定しなければムーブ型になるが
コピー型にしたいならばこう宣言すれば挙動がムーブではなくコピーとなる
#[derive(Copy, Clone)]
struct Foo(i32, i32);
let mut p = Foo(123, 456);
let q = p;
p.0 = 789;
assert!(p.0 != q.0);
assert!(p.1 == q.1);
2023/04/22(土) 17:41:44.05ID:+yUQZ3bR
>>359
実行時に参照カウントが2以上ならエラーとなる型もRustでは作れるよ
でももっと便利な仕様「実行時に(可変でない)参照カウントはいくつ増えてもOKだけど、可変参照を得る時だけは独占的つまり参照カウントが0でないとエラー」がもっと便利
標準ライブラリRefCell<T>がその仕様そのままで
RefCell<T>自体の可変参照を持っていなくて(非可変)参照を持ってるだけでもTを書き換えることができちゃう
Rustの厳しい可変参照ルールを無視できるから便利だね
いわゆる内部可変性と呼ばれる型の一つ
2023/04/22(土) 18:24:59.90ID:/en2DlgL
>>364
Rc<T>とRefCell<T>に互換性のようなものはないから「もっと便利」というのは違和感がある
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況