「C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな」
「うだうだ言ってないで仕事で必要なのをやればいいんだよ、趣味なら好きなのやればいい」
っていうスレ。
前スレ: 結局C++とRustってどっちが良いの?
https://mevius.5ch.net/test/read.cgi/tech/1677286186/
探検
結局C++とRustってどっちが良いの? 2traits
■ このスレッドは過去ログ倉庫に格納されています
2023/04/02(日) 00:42:57.53ID:W9/nq+tL
271デフォルトの名無しさん
2023/04/19(水) 14:59:19.03ID:4c9fSoSa 思わぬところに反論しときたいんだが
>>265
> 何度も何度も何度もプロたちがミスってきた
ここはちょっと要検証じゃね たとえば、Chromium/Chromeは精鋭だけで書かれたのか
ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、静的解析に通るように綺麗に書く
だから、「馬鹿にするな、C++が悪いんじゃない、悪い奴が悪いんだ」って反論も出る
C++はプロじゃない人間も使う、例えば俺 だから、C++にもunsafe{ } が必要なんだ
些細なようだが、ちゃんとしてるプロをバカにすることはない
敬意を払うのは人の為ならず(自分のため)
>>265
> 何度も何度も何度もプロたちがミスってきた
ここはちょっと要検証じゃね たとえば、Chromium/Chromeは精鋭だけで書かれたのか
ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、静的解析に通るように綺麗に書く
だから、「馬鹿にするな、C++が悪いんじゃない、悪い奴が悪いんだ」って反論も出る
C++はプロじゃない人間も使う、例えば俺 だから、C++にもunsafe{ } が必要なんだ
些細なようだが、ちゃんとしてるプロをバカにすることはない
敬意を払うのは人の為ならず(自分のため)
272デフォルトの名無しさん
2023/04/19(水) 16:01:07.64ID:mEvWDtbQ >>271
>ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、
使いこなすって表現するほどスマートポインタは御大層なものではない
そもそもmake_uniquやmake_sharedするのは
俺の場合は全インスタンスの1割弱だよ(newは一切無い)
operator newを呼ばずにインスタンスを作るのが9割超
>ガチプロはそんなミスしないんだよ、ガチプロはスマポを使いこなすし、
使いこなすって表現するほどスマートポインタは御大層なものではない
そもそもmake_uniquやmake_sharedするのは
俺の場合は全インスタンスの1割弱だよ(newは一切無い)
operator newを呼ばずにインスタンスを作るのが9割超
273デフォルトの名無しさん
2023/04/19(水) 16:53:43.84ID:ZJsXKDj1 >>264
>C++だって、「そんな書き方すんなよ」ってのを踏むヤツが後を絶たない
これな
前にも誰か言ってたが vector にぶっこんだデータを参照するときに
再配置が起きると参照先が無くなって困るとか
そりゃ再配置が起きるような書き方してる方が悪いんだよ
>C++だって、「そんな書き方すんなよ」ってのを踏むヤツが後を絶たない
これな
前にも誰か言ってたが vector にぶっこんだデータを参照するときに
再配置が起きると参照先が無くなって困るとか
そりゃ再配置が起きるような書き方してる方が悪いんだよ
274デフォルトの名無しさん
2023/04/19(水) 18:49:07.48ID:s8p2Q+oA よくわからんが、プログラマーはlifetimeのパラメーターを明示的に実体化できないんだよね
人間の代わりにコンパイラが暗黙に自動的に実体化する
なんで人間が何か踏んだとか人間が穴に落ちたみたいに言われてるんだ?
人間の代わりにコンパイラが暗黙に自動的に実体化する
なんで人間が何か踏んだとか人間が穴に落ちたみたいに言われてるんだ?
275デフォルトの名無しさん
2023/04/19(水) 19:51:56.67ID:ckDmN3Ij コンパイラが調整する余白部分はあるけど包含関係を明示する程度にはプログラマが指定できる
ライフタイムは
「関数内のローカル変数の参照を関数の外にreturnしても受け取った側では使えなくなってる」
みたいなC++でも一般的なルールを概念的に表してるだけだよ
関数じゃなくブロック単位でスタックを伸縮させるコード生成があるかは知らないけど
ライフタイムはスタックのどの辺にそのデータ(の根拠)が置かれているかにおよそ対応してて
スタックの先端の方ほどライフタイムは短くなるし根元に近いほどライフタイムは長くなる
参照値の場所より根元の方を参照する分にはとりあえず安全だけど参照値より先端の方を参照してると
知らないうちに処理が進んでスタックが短縮されて参照先が無効になるかもしれない
そういう参照エラーをコンパイラで排除するためにライフタイムが使われてる
参照先は参照元より根元に近い(長生きする)ことが保証されてる範囲でしか認めない感じかな
実際は参照値もデータもスタック上で引っ越したりするし
被参照中はそのデータが動かせなくなるみたいな別のルールもあるからややこしいけど
ライフタイムは
「関数内のローカル変数の参照を関数の外にreturnしても受け取った側では使えなくなってる」
みたいなC++でも一般的なルールを概念的に表してるだけだよ
関数じゃなくブロック単位でスタックを伸縮させるコード生成があるかは知らないけど
ライフタイムはスタックのどの辺にそのデータ(の根拠)が置かれているかにおよそ対応してて
スタックの先端の方ほどライフタイムは短くなるし根元に近いほどライフタイムは長くなる
参照値の場所より根元の方を参照する分にはとりあえず安全だけど参照値より先端の方を参照してると
知らないうちに処理が進んでスタックが短縮されて参照先が無効になるかもしれない
そういう参照エラーをコンパイラで排除するためにライフタイムが使われてる
参照先は参照元より根元に近い(長生きする)ことが保証されてる範囲でしか認めない感じかな
実際は参照値もデータもスタック上で引っ越したりするし
被参照中はそのデータが動かせなくなるみたいな別のルールもあるからややこしいけど
276デフォルトの名無しさん
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;
}
以下は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;
}
277デフォルトの名無しさん
2023/04/20(木) 00:51:46.92ID:iAIcEMT7 そ、そんなに言うんだったら、お、俺もRust始めてみるよ
278デフォルトの名無しさん
2023/04/20(木) 01:16:01.15ID:GPVFd3S9279デフォルトの名無しさん
2023/04/20(木) 01:19:28.98ID:GPVFd3S9 他言語なら0..min(v.len(), size)とかもあるだろうけどRustではあんまりやらないと思う
280デフォルトの名無しさん
2023/04/20(木) 01:22:50.03ID:9yNISOE6 Rustにはindexでアクセスするコンテナってやっぱないのかな?
281デフォルトの名無しさん
2023/04/20(木) 01:24:33.22ID:9yNISOE6282デフォルトの名無しさん
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}");
}
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}");
}
283デフォルトの名無しさん
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では普通
for i in (0..v.len()).take_while(|&i| i < input_size) {
let n = v[i];
println!("n={n}");
}
3つとも同じ動作となるけど
簡潔かつインデックス不要な最初の方法がRustでは普通
284デフォルトの名無しさん
2023/04/20(木) 01:56:51.02ID:9yNISOE6285デフォルトの名無しさん
2023/04/20(木) 01:59:04.25ID:9yNISOE6 >>282,283
3つともunsafeで囲まなくてもコンパイルは通るのでしょうか?
3つともunsafeで囲まなくてもコンパイルは通るのでしょうか?
286デフォルトの名無しさん
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を閉じ込めて安全なインタフェースを提供する場合
イテレータのtake(n)は最大n個になる
その前のv.iter()からv.len()個の参照が来る
だからnがv.len()より多くてもそれ以上ポインタは進まず安全
>>285
unsafeは必要ない
自分ですぐ試せるからここで何でもやってみればいい
https://play.rust-lang.org/
Rustで普通に使っていてunsafeは出て来ない
unsafeが出てくるのは例えば
FFIでC言語など別言語からの変換とか
既存ライブラリにない新たな仕組みの型を作り出すときに
unsafeを使わざるを得なくてunsafeを閉じ込めて安全なインタフェースを提供する場合
287デフォルトの名無しさん
2023/04/20(木) 02:38:45.55ID:9yNISOE6288デフォルトの名無しさん
2023/04/20(木) 02:54:57.60ID:px2D1mrK289デフォルトの名無しさん
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}");
}
以下だとコンパイルは通らないんだよね?
for i in (0..100).take_while(|&i| i < input_size) {
let n = v[i];
println!("n={n}");
}
290デフォルトの名無しさん
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での普通の書き方
そこには借用(ボロー)つまり参照がないからボローチェッカーは無関係
厳密には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での普通の書き方
291デフォルトの名無しさん
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はメモリアクセス違反を何でもかんでもコンパイルで弾けるわけじゃないのね
なるほど
>ちなみにC以外ほとんどの言語と同様に v[i] は安全にインデックス範囲チェックが行われる
C++でいうと以下のような感じなのかな?
for (size_t i {0}; i < input_size; ++ i)
cout << v.at (i) << '\n';
Rustはメモリアクセス違反を何でもかんでもコンパイルで弾けるわけじゃないのね
292デフォルトの名無しさん
2023/04/20(木) 11:20:58.88ID:ViRjvm8y アクセス違反が発生しても何となく動き続けることがなければとりあえずセーフの精神
unsafe内でuncheckにするオプションも用意されてることが多いけど
unsafe内でuncheckにするオプションも用意されてることが多いけど
293デフォルトの名無しさん
2023/04/20(木) 11:29:56.72ID:vzrku2iH DoSにつながるから、落ちるのはよくないみたいに言われたりするんだけど、
変に無理に動き続けるより、異常を見つけたら落としたほうがいいときってあると思うんだよな
落ちるバグはコールスタック残ってればいち早く潰すだろうし
変に無理に動き続けるより、異常を見つけたら落としたほうがいいときってあると思うんだよな
落ちるバグはコールスタック残ってればいち早く潰すだろうし
294デフォルトの名無しさん
2023/04/20(木) 11:44:16.22ID:GPVFd3S9 バッファオーバーフローみたいな脆弱性につながるから落とすほうが安全なんだよ
295デフォルトの名無しさん
2023/04/20(木) 11:48:21.96ID:SYxH5KMK C/C++とは異なり、Rustは範囲外メモリアクセスを絶対に起こさないことが保証される点が決定的な違い
シーケンシャルアクセスでは、Rustではv.iter()とイテレータを使い、結果的に終端アドレスに達するまでポインタが進むのと同じ生成コードになるので、最高速かつ安全に範囲内のみのコードになる
そのうえで、v.iter().take(input_size)など様々な条件や加工などをするイテレータメソッドを複数組み合わせて、メソッドチェーンにより簡潔な記述をするのがRustでの書き方
シーケンシャルアクセスでは、Rustではv.iter()とイテレータを使い、結果的に終端アドレスに達するまでポインタが進むのと同じ生成コードになるので、最高速かつ安全に範囲内のみのコードになる
そのうえで、v.iter().take(input_size)など様々な条件や加工などをするイテレータメソッドを複数組み合わせて、メソッドチェーンにより簡潔な記述をするのがRustでの書き方
296デフォルトの名無しさん
2023/04/20(木) 13:05:49.56ID:9yNISOE6 >>295
ディフェンスラインが後退したな
STLのコンテナもatでアクセスすれば範囲外アクセスで例外を投げるので同じ
オーバーヘッドが気になるならoperator[]によるアクセスも
イテレータによるアクセスも選択できる
ディフェンスラインが後退したな
STLのコンテナもatでアクセスすれば範囲外アクセスで例外を投げるので同じ
オーバーヘッドが気になるならoperator[]によるアクセスも
イテレータによるアクセスも選択できる
297デフォルトの名無しさん
2023/04/20(木) 13:34:13.29ID:w/28tNmU C/C++はポインタと配列の区別があやふやだ
まず配列という概念がない言語でポインタの問題だけを解決し
それから配列をたんなるライブラリとして追加するほうが無駄なトラブルが少ない
配列すらない状態に一旦後退するのは正しい
その意味では、ジェネリクスがない状態に後退できるC/C++を見習うべきだったとも言える
まず配列という概念がない言語でポインタの問題だけを解決し
それから配列をたんなるライブラリとして追加するほうが無駄なトラブルが少ない
配列すらない状態に一旦後退するのは正しい
その意味では、ジェネリクスがない状態に後退できるC/C++を見習うべきだったとも言える
298デフォルトの名無しさん
2023/04/20(木) 18:25:05.04ID:zqUq/1wh299デフォルトの名無しさん
2023/04/20(木) 19:53:34.14ID:9yNISOE6300デフォルトの名無しさん
2023/04/20(木) 20:48:09.87ID:D1KovJeq Rustもインデックス範囲内チェックの有り無しを選べる
基本的にはインデックスは使われず、安全な範囲内に動くポインタのみを、自在に各種イテレータメソッドで扱うため、オーバーヘッドはゼロ
唯一の例外が真のランダムアクセスで、範囲内のインデックス値か不明なものを扱うため、インデックス毎に範囲内チェックは絶対に不可避なためコストがかかる
その場合でも、範囲内のインデックス値しか来ない構造ならば、新たな型をunsafeなget_unchecked()を用いてそれを閉じ込めて、安全なインターフェースとして提供できるため、オーバーヘッドはゼロ
基本的にはインデックスは使われず、安全な範囲内に動くポインタのみを、自在に各種イテレータメソッドで扱うため、オーバーヘッドはゼロ
唯一の例外が真のランダムアクセスで、範囲内のインデックス値か不明なものを扱うため、インデックス毎に範囲内チェックは絶対に不可避なためコストがかかる
その場合でも、範囲内のインデックス値しか来ない構造ならば、新たな型をunsafeなget_unchecked()を用いてそれを閉じ込めて、安全なインターフェースとして提供できるため、オーバーヘッドはゼロ
301デフォルトの名無しさん
2023/04/20(木) 21:12:04.09ID:8LRk4zHW >>300
それC++と何が違うのかな?
それC++と何が違うのかな?
302デフォルトの名無しさん
2023/04/20(木) 21:17:13.53ID:B6QJskar チェックを忘れて脆弱性を埋め込むリスクが桁違い
303デフォルトの名無しさん
2023/04/20(木) 21:33:10.92ID:9yNISOE6304デフォルトの名無しさん
2023/04/20(木) 21:38:15.36ID:iAIcEMT7 >その場合でも、範囲内のインデックス値しか来ない構造ならば
この判断を誤ると結局脆弱性が埋め込まれそうだけど、
チェックを忘れることに比べれば起こりにくいのかもね
この判断を誤ると結局脆弱性が埋め込まれそうだけど、
チェックを忘れることに比べれば起こりにくいのかもね
305デフォルトの名無しさん
2023/04/20(木) 21:40:24.96ID:SYxH5KMK306デフォルトの名無しさん
2023/04/20(木) 21:40:47.43ID:9yNISOE6 私は違いがサッパリ分からんぞ
307デフォルトの名無しさん
2023/04/20(木) 21:44:22.16ID:9yNISOE6308デフォルトの名無しさん
2023/04/20(木) 21:51:17.50ID:D1KovJeq309デフォルトの名無しさん
2023/04/20(木) 21:56:16.00ID:9yNISOE6310デフォルトの名無しさん
2023/04/20(木) 22:01:05.35ID:9yNISOE6 >>307
私はせっかちなので自分で議論を進めると(と言っても私はRustは分からんのだが)
範囲外チェックなしでインデックスでアクセスできる -> Rustも同様に危険
範囲外チェックなしでインデックスでアクセスできない -> Rustはオーバヘッドがある
ということになる
私はせっかちなので自分で議論を進めると(と言っても私はRustは分からんのだが)
範囲外チェックなしでインデックスでアクセスできる -> Rustも同様に危険
範囲外チェックなしでインデックスでアクセスできない -> Rustはオーバヘッドがある
ということになる
311デフォルトの名無しさん
2023/04/20(木) 22:03:11.36ID:cejxbewD 複オジの説明がクソだから伝わらなくても仕方ない
312デフォルトの名無しさん
2023/04/20(木) 22:06:37.25ID:9yNISOE6313デフォルトの名無しさん
2023/04/20(木) 22:18:01.10ID:FIsyFWOj C++に勝ってると主張するために普段はunsafeのことを脇に置いてメリットばっかり語ってるのに
性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出すからややこしいことになるんじゃな
性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出すからややこしいことになるんじゃな
314デフォルトの名無しさん
2023/04/20(木) 22:26:58.01ID:dJqrvGvM 昔LISPもそれでCと張り合ってたな
歴史は繰り返すんやな
歴史は繰り返すんやな
315デフォルトの名無しさん
2023/04/20(木) 22:36:42.26ID:98y/hYCF 話は簡単
RustはVecもそこで使われるスライスのイテレータも
unsafeなコードを閉じ込めてsafeなメソッドを提供している
だからその部分の作成は人間がミスるとおしまい
逆に言えばその狭い範囲のみ人間が頑張って安全性を保証すればよい
一方でそれらVecやイテレータなどを利用する一般のプログラマーは
そのsafeなメソッドを使っている限り絶対に安全なことが保証される
もし問題があればコンパイラがエラーを出すので常に安全となる
結論
RustもC++も最小限のオーバーヘッドが可能で同じ
しかしその安全性は全く異なる
C++は常にミスったらおしまい
C++はプログラム全体に対して人間が安全性を保証しなければならない
Rustはsafe利用者がミスることは絶対になくコンパイラがエラーを出してくれる
Rustはunsafe利用部分のみ人間が安全性を保証しなければならない
RustはVecもそこで使われるスライスのイテレータも
unsafeなコードを閉じ込めてsafeなメソッドを提供している
だからその部分の作成は人間がミスるとおしまい
逆に言えばその狭い範囲のみ人間が頑張って安全性を保証すればよい
一方でそれらVecやイテレータなどを利用する一般のプログラマーは
そのsafeなメソッドを使っている限り絶対に安全なことが保証される
もし問題があればコンパイラがエラーを出すので常に安全となる
結論
RustもC++も最小限のオーバーヘッドが可能で同じ
しかしその安全性は全く異なる
C++は常にミスったらおしまい
C++はプログラム全体に対して人間が安全性を保証しなければならない
Rustはsafe利用者がミスることは絶対になくコンパイラがエラーを出してくれる
Rustはunsafe利用部分のみ人間が安全性を保証しなければならない
316デフォルトの名無しさん
2023/04/20(木) 22:42:39.55ID:9yNISOE6317デフォルトの名無しさん
2023/04/20(木) 22:43:11.74ID:98y/hYCF >>313
そのunsafeなget_uncheckedの件も同じ
unsafeを利用してsafeを提供する人だけがその安全性の保証できるコードを書けばよい
一方でそこで作られたsafeなものを利用する一般プログラマーはミスってもコンパイラがエラーとして止めてくれる
そのunsafeなget_uncheckedの件も同じ
unsafeを利用してsafeを提供する人だけがその安全性の保証できるコードを書けばよい
一方でそこで作られたsafeなものを利用する一般プログラマーはミスってもコンパイラがエラーとして止めてくれる
318デフォルトの名無しさん
2023/04/20(木) 22:44:27.28ID:9yNISOE6319デフォルトの名無しさん
2023/04/20(木) 22:44:35.26ID:98y/hYCF >>316
Rustではコンパイル時に安全性を必ずチェックできる
Rustではコンパイル時に安全性を必ずチェックできる
320デフォルトの名無しさん
2023/04/20(木) 22:48:29.32ID:9yNISOE6321デフォルトの名無しさん
2023/04/20(木) 22:49:34.33ID:98y/hYCF322デフォルトの名無しさん
2023/04/20(木) 22:55:08.59ID:98y/hYCF >>320
最初に出ているこのコードのことだろ
for n in v.iter().take(input_size) {
println!("{n}");
}
もちろんinput_sizeの値に関わらず静的に安全なコードだ
そしてインデックスは用いないのでインデックス範囲外チェックは無い
Cでポインタで書いたときと同じ速度になる
最初に出ているこのコードのことだろ
for n in v.iter().take(input_size) {
println!("{n}");
}
もちろんinput_sizeの値に関わらず静的に安全なコードだ
そしてインデックスは用いないのでインデックス範囲外チェックは無い
Cでポインタで書いたときと同じ速度になる
323デフォルトの名無しさん
2023/04/20(木) 22:56:41.18ID:9yNISOE6 議論にならんのでスルーして
彼の主張は(正しいのかは分からんが)
要するに範囲外チェックなしでインデックスでアクセスできるということだから
Rustも同様にこの点は危険ということになる
彼の主張は(正しいのかは分からんが)
要するに範囲外チェックなしでインデックスでアクセスできるということだから
Rustも同様にこの点は危険ということになる
324デフォルトの名無しさん
2023/04/20(木) 23:00:30.54ID:9yNISOE6325デフォルトの名無しさん
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の値のみをとるため)
将棋の実装を実際にしたことはないが
似たようなデータ型は実際に何度か書いたことがある
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の値のみをとるため)
将棋の実装を実際にしたことはないが
似たようなデータ型は実際に何度か書いたことがある
326デフォルトの名無しさん
2023/04/20(木) 23:29:13.60ID:vzrku2iH C/C++にも、-fsanitize=address ってのが後追いながらちゃんと入ってきてる
その価値は認めていいし、しかし、差は縮まりつつある
その価値は認めていいし、しかし、差は縮まりつつある
327デフォルトの名無しさん
2023/04/20(木) 23:32:10.47ID:vzrku2iH Rustでも、unsafe が抜け穴になるよね、って反論はつまり、
コピペ勢に対して、「いやみんなばんばんunsafe使っちゃうからダウト」って返してるってことw
ここにたまるようなヤツは、必要に応じてモジュール毎にON/OFFくらいできるヤツ
熱心に張り合うまでもなく、有意義に使うよ
コピペ勢に対して、「いやみんなばんばんunsafe使っちゃうからダウト」って返してるってことw
ここにたまるようなヤツは、必要に応じてモジュール毎にON/OFFくらいできるヤツ
熱心に張り合うまでもなく、有意義に使うよ
328デフォルトの名無しさん
2023/04/20(木) 23:56:26.81ID:98y/hYCF わずかなunsafe封じ込め部分だけに注力することで、効率的なsafeを作ってしまえば、safe利用者はコンパイラに安全性の保証を任せられることがRustの最大のメリット
329デフォルトの名無しさん
2023/04/21(金) 00:05:38.80ID:SijbBkLt わずかになってくれればいいね
ああ、また釣られてしまったw
ああ、また釣られてしまったw
330デフォルトの名無しさん
2023/04/21(金) 00:13:14.15ID:4oRlgId+331デフォルトの名無しさん
2023/04/21(金) 00:14:20.12ID:4oRlgId+ まちごうた
-9yNISOE6の主張が正しいと仮定して
+98y/hYCFの主張が正しいと仮定して
-9yNISOE6の主張が正しいと仮定して
+98y/hYCFの主張が正しいと仮定して
332デフォルトの名無しさん
2023/04/21(金) 00:14:28.54ID:7fROJFuD 最適化はunsafeというのはRustではほぼ客観的事実に近い
C++で似たような意見を言えば、最適化の足を引っ張る陰謀と見分けがつかない者もいるだろう
C++で似たような意見を言えば、最適化の足を引っ張る陰謀と見分けがつかない者もいるだろう
333デフォルトの名無しさん
2023/04/21(金) 00:19:35.15ID:9IEMPFWw 範囲がconst/constexprであれば、チェックコストはゼロにしうるのでは
そこにコストをかけてでもsafeにしましょうというのがモダン(含Rust)
そこにコストがかからないように書いてナンボなのがC++(失敗時は: 安全だがコストが生じる)
そこにコストをかけてでもsafeにしましょうというのがモダン(含Rust)
そこにコストがかからないように書いてナンボなのがC++(失敗時は: 安全だがコストが生じる)
334デフォルトの名無しさん
2023/04/21(金) 00:58:19.29ID:9IEMPFWw 関係あると思うのできかせて
いまさら人に聞けないんだが、Intel MPXってのが早々にディスコンになったのは、
・MPXでも抜けがあることがわかった
・いまやパイプライン? が優秀すぎて、MPXでもソフトウェア サニタイザでもそんな変わらなかった
っていう理解をしてるけど合ってる?
いまさら人に聞けないんだが、Intel MPXってのが早々にディスコンになったのは、
・MPXでも抜けがあることがわかった
・いまやパイプライン? が優秀すぎて、MPXでもソフトウェア サニタイザでもそんな変わらなかった
っていう理解をしてるけど合ってる?
335デフォルトの名無しさん
2023/04/21(金) 01:08:57.82ID:mE/p3bqb336デフォルトの名無しさん
2023/04/21(金) 02:33:15.05ID:9IEMPFWw かのIntel(当時)が頑張ってもこんなもん(こんなことになる)か
難しいもんなんだな。。
俺にできないだけで、本気出せば難しくないもんかと思ってたのに
難しいもんなんだな。。
俺にできないだけで、本気出せば難しくないもんかと思ってたのに
337デフォルトの名無しさん
2023/04/21(金) 05:31:12.23ID:7fROJFuD 具体的に誰が頑張ったのか全然わからない
いまさら英雄化してももう遅い
いまさら英雄化してももう遅い
338デフォルトの名無しさん
2023/04/21(金) 09:34:15.68ID:Jt0l0JSP339デフォルトの名無しさん
2023/04/21(金) 10:24:01.60ID:YWjwap1N play.rust-lang.org で
use rstk::*; とか
use wx; とか
もちろん出来ない訳だが
use したときに一瞬一覧で選べるものが出て来るので
これの一覧をテキストファイルで欲しいんだが
どこで観れますか?
use rstk::*; とか
use wx; とか
もちろん出来ない訳だが
use したときに一瞬一覧で選べるものが出て来るので
これの一覧をテキストファイルで欲しいんだが
どこで観れますか?
340デフォルトの名無しさん
2023/04/21(金) 10:33:13.77ID:YWjwap1N >C++に勝ってると主張するために普段はunsafeのことを脇に置いてメリットばっかり語ってるのに
>性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出す
ほんそれ
>性能で負けてるって言われて悔しいからって急にget_uncheckedの話持ち出す
ほんそれ
341デフォルトの名無しさん
2023/04/21(金) 11:32:23.34ID:obBiE3Vg342デフォルトの名無しさん
2023/04/21(金) 15:41:39.16ID:YWjwap1N343デフォルトの名無しさん
2023/04/21(金) 16:08:14.43ID:e/N20Lgf >>342
それは自分の環境でどうぞ
それは自分の環境でどうぞ
344デフォルトの名無しさん
2023/04/21(金) 21:37:21.45ID:AfLtEamq 控えめに言って Rust は超マゾ言語
345デフォルトの名無しさん
2023/04/21(金) 23:59:16.40ID:LZBHeARm C++もRustも基本的には変わらん
C++で常に安全に書ける人にとってライフタイムなんてすぐ理解できて困らん普通のことだった
Rustでいいと思ったのはイテレータメソッドチェーンのシンプルさとか
あらゆる部分でパターンマッチングできる点とか
C++で常に安全に書ける人にとってライフタイムなんてすぐ理解できて困らん普通のことだった
Rustでいいと思ったのはイテレータメソッドチェーンのシンプルさとか
あらゆる部分でパターンマッチングできる点とか
346デフォルトの名無しさん
2023/04/22(土) 00:04:17.51ID:L3G+XloM GC言語は良いと思うし使いけど可視化する気にならない
GC言語が多過ぎるから
Python並みの人気でも過半数に支持されるとは思えない
GC言語が多過ぎるから
Python並みの人気でも過半数に支持されるとは思えない
347デフォルトの名無しさん
2023/04/22(土) 01:08:10.55ID:6MRD/fZf ライフタイム付き再帰構造体を再帰関数で回してlifetimeのvarianceで苦しむまでがボローチェッカチュートリアルです
348デフォルトの名無しさん
2023/04/22(土) 05:11:35.36ID:ve/ll5uR Rustの弱点突きまくり
349デフォルトの名無しさん
2023/04/22(土) 07:15:46.36ID:iD47eBZH 言語(Rust含む)がせっかく親切にしてくれてるのに、その虚を突く
…っていうか、虚を天然で踏み抜いちゃうのが、シロウトなんだよなあ 俺含む(自戒
…っていうか、虚を天然で踏み抜いちゃうのが、シロウトなんだよなあ 俺含む(自戒
350デフォルトの名無しさん
2023/04/22(土) 07:19:16.96ID:UYc1nlSd PythonのAI系のライブラリを
rustで作り直したら爆速になるのかな?
rustで作り直したら爆速になるのかな?
351デフォルトの名無しさん
2023/04/22(土) 07:23:17.49ID:iD47eBZH 大人気のCUDA版は、CUDAでできてるから Pythonで操ってるだけ
352デフォルトの名無しさん
2023/04/22(土) 09:44:15.55ID:UBHQks3G C++のライフタイムが本当に簡単ならライフタイム系のバグを100%検知できるツールなんて簡単に作れるはずだよね?
353デフォルトの名無しさん
2023/04/22(土) 09:50:17.61ID:OMpDwvP8 >>352
そういう意味ではなく逆だろ
C++でもともなコードを書けているプログラマーはRustでライフタイムをすぐ習得してしまう話だろう
逆にライフタイムを難しいと言ってるプログラマーはC++で込み入ってくると正しいコードを書けない
そういう意味ではなく逆だろ
C++でもともなコードを書けているプログラマーはRustでライフタイムをすぐ習得してしまう話だろう
逆にライフタイムを難しいと言ってるプログラマーはC++で込み入ってくると正しいコードを書けない
354デフォルトの名無しさん
2023/04/22(土) 10:40:59.94ID:iD47eBZH355デフォルトの名無しさん
2023/04/22(土) 10:48:04.53ID:/en2DlgL varianceをOOPにたとえると
変数の型を宣言できないが基底クラスなら宣言できる
という理解でいいんでしょ
変数の型を宣言するツールを簡単に作れるかが問題なのでは
変数の型を宣言できないが基底クラスなら宣言できる
という理解でいいんでしょ
変数の型を宣言するツールを簡単に作れるかが問題なのでは
356デフォルトの名無しさん
2023/04/22(土) 10:54:03.92ID:8hXabeY8 ポインタと同じでライフタイムも概念を理解するのは何も難しいことはない
バグなしで使いこなすのが難しいだけ
それだからRustは厳しめのルールにしてコンパイラでチェックする
C++が脆弱性を量産してきた負の遺産を継承しないためにね
バグなしで使いこなすのが難しいだけ
それだからRustは厳しめのルールにしてコンパイラでチェックする
C++が脆弱性を量産してきた負の遺産を継承しないためにね
357デフォルトの名無しさん
2023/04/22(土) 11:23:28.94ID:XW9UuYWq358デフォルトの名無しさん
2023/04/22(土) 12:09:24.25ID:SKSgk+MB 少し前にvectorの再配置の例が出てたけど
他で参照してる間にデータを操作して参照がおかしくなる事故が後を絶たないから仕方ない
普通のイテレータで走査してる最中に要素を削除したりとか
他で参照してる間にデータを操作して参照がおかしくなる事故が後を絶たないから仕方ない
普通のイテレータで走査してる最中に要素を削除したりとか
359デフォルトの名無しさん
2023/04/22(土) 12:57:45.65ID:/en2DlgL360デフォルトの名無しさん
2023/04/22(土) 13:13:05.95ID:XW9UuYWq >>358
それはどういう状況かな?
それはどういう状況かな?
361デフォルトの名無しさん
2023/04/22(土) 13:44:44.50ID:3JkCsMe2 RustはまだMicrosoftがVisualRust出してないしなあ…
362デフォルトの名無しさん
2023/04/22(土) 15:25:53.88ID:V6k8LZu5 Microsoft方言なRustとかはいらん
363デフォルトの名無しさん
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);
所有権システムは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);
364デフォルトの名無しさん
2023/04/22(土) 17:41:44.05ID:+yUQZ3bR >>359
実行時に参照カウントが2以上ならエラーとなる型もRustでは作れるよ
でももっと便利な仕様「実行時に(可変でない)参照カウントはいくつ増えてもOKだけど、可変参照を得る時だけは独占的つまり参照カウントが0でないとエラー」がもっと便利
標準ライブラリRefCell<T>がその仕様そのままで
RefCell<T>自体の可変参照を持っていなくて(非可変)参照を持ってるだけでもTを書き換えることができちゃう
Rustの厳しい可変参照ルールを無視できるから便利だね
いわゆる内部可変性と呼ばれる型の一つ
実行時に参照カウントが2以上ならエラーとなる型もRustでは作れるよ
でももっと便利な仕様「実行時に(可変でない)参照カウントはいくつ増えてもOKだけど、可変参照を得る時だけは独占的つまり参照カウントが0でないとエラー」がもっと便利
標準ライブラリRefCell<T>がその仕様そのままで
RefCell<T>自体の可変参照を持っていなくて(非可変)参照を持ってるだけでもTを書き換えることができちゃう
Rustの厳しい可変参照ルールを無視できるから便利だね
いわゆる内部可変性と呼ばれる型の一つ
365デフォルトの名無しさん
2023/04/22(土) 18:24:59.90ID:/en2DlgL >>364
Rc<T>とRefCell<T>に互換性のようなものはないから「もっと便利」というのは違和感がある
Rc<T>とRefCell<T>に互換性のようなものはないから「もっと便利」というのは違和感がある
366デフォルトの名無しさん
2023/04/22(土) 18:42:18.67ID:+yUQZ3bR367デフォルトの名無しさん
2023/04/22(土) 18:45:43.59ID:pFB+K5t4 話が専門的になってきているけれども、「メモリー関連バグ」はバグの一部に
過ぎず、それが完全に防げたとしてもバグが入り込む余地はたくさんある。
例えば、JSやJava、C#、BASIC、Pythonなどの言語はメモリー関連バグは
入り込まないが、バグはいくらでも入り込む。
過ぎず、それが完全に防げたとしてもバグが入り込む余地はたくさんある。
例えば、JSやJava、C#、BASIC、Pythonなどの言語はメモリー関連バグは
入り込まないが、バグはいくらでも入り込む。
368デフォルトの名無しさん
2023/04/22(土) 18:51:49.24ID:iD47eBZH Javaはぬるぽぬるぽいってたけどねえ いまさらだけど、あれなんだったんだろう (nullptrは使ってます
369デフォルトの名無しさん
2023/04/22(土) 19:01:05.60ID:pFB+K5t4 >>367
追加として、Ruby、PHP、Perl なども同様。
メモリー関連バグは入らないが、論理バグはいくらでも入り込む。
だから、ネットショッピングサイトをこれらの言語で作っても、
データ漏洩や、データ消失(顧客情報の間違った削除など)、
インターフェースのバグ、買いたいものが買えない、別人のアカウントで
買った事になってしまう、あるいは、セキュリティーホールなどは、
入り込む余地はいくらでもある。
15 番の人が購入しているのに、16番の人を購入したことにしてしまったりとか。
または、ボタンを一回押したのに、2回購入したことになってしまったとか。
キャンセルボタンを押しても動作しないとか。
または、キャンセルすると、14番の人の購入がキャンセルしてしまったりとか。
そういうのは基本的に論理バグであり、メモリー関連バグとは別に発生しうる。
追加として、Ruby、PHP、Perl なども同様。
メモリー関連バグは入らないが、論理バグはいくらでも入り込む。
だから、ネットショッピングサイトをこれらの言語で作っても、
データ漏洩や、データ消失(顧客情報の間違った削除など)、
インターフェースのバグ、買いたいものが買えない、別人のアカウントで
買った事になってしまう、あるいは、セキュリティーホールなどは、
入り込む余地はいくらでもある。
15 番の人が購入しているのに、16番の人を購入したことにしてしまったりとか。
または、ボタンを一回押したのに、2回購入したことになってしまったとか。
キャンセルボタンを押しても動作しないとか。
または、キャンセルすると、14番の人の購入がキャンセルしてしまったりとか。
そういうのは基本的に論理バグであり、メモリー関連バグとは別に発生しうる。
370デフォルトの名無しさん
2023/04/22(土) 19:24:40.58ID:2MwGVm8+ >>367
GC言語を含めた多くの言語で発生する普遍的なバグがデータ競合
データ競合は様々なものがあってマルチスレッドでは当然発生するだけでなく
スレッドを利用しなくても部分参照が可能な言語ではデータ競合が容易に発生してしまう
後者の例はこのスレ既出でベクター型においてその何番目かの要素の参照を持っているときに
要素追加が行われると再配置によりダングリングを引き起こしたり
要素挿入が行われると再配置がなくてもズレて意図せず異なる要素を指してしまうデータ競合が起きる
>>369の例の別の人の購入データになってしまったりするバグも様々なデータ競合により引き起こされることが多い
このように色々なデータ競合がプログラミングで発生するが
Rustではデータ競合が発生せずコンパイルエラーとなる
これは非常に大きな強み
GC言語を含めた多くの言語で発生する普遍的なバグがデータ競合
データ競合は様々なものがあってマルチスレッドでは当然発生するだけでなく
スレッドを利用しなくても部分参照が可能な言語ではデータ競合が容易に発生してしまう
後者の例はこのスレ既出でベクター型においてその何番目かの要素の参照を持っているときに
要素追加が行われると再配置によりダングリングを引き起こしたり
要素挿入が行われると再配置がなくてもズレて意図せず異なる要素を指してしまうデータ競合が起きる
>>369の例の別の人の購入データになってしまったりするバグも様々なデータ競合により引き起こされることが多い
このように色々なデータ競合がプログラミングで発生するが
Rustではデータ競合が発生せずコンパイルエラーとなる
これは非常に大きな強み
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【無言】中国怒らせた高市首相→1週間だんまり、国民に実害も説明なし 中国問題を避けてスルー… ★2 [BFU★]
- 止まらぬ「日本売り」 高市財政への懸念で進む金利上昇と円安 [蚤の市★]
- 【いちご高騰】ヤマザキのクリスマスケーキ、いちご無し販売 [おっさん友の会★]
- 【日中対立】 朝日新聞のタイトル修正が中国逆ギレの火種か SNSで批判相次ぐ [♪♪♪★]
- ネット殺到「高市総理の責任」「完全に高市リスク」「負けるな」中国が水産物輸入停止→流石に総理批判の声も「どう責任取る?」 ★10 [樽悶★]
- 【MLB】ドジャース・山本由伸と渦中の村上宗隆が会食 米メディア騒然 「村上と大谷翔平が同じ打線に並ぶ姿を想像してみてほしい」 [冬月記者★]
- 中国「高市が謝罪しなければ、ハニトラに引っかかった日本の政治家を公表する」 [804169411]
- お前らなんでそんなに冷静なの
- (´・ω・`)もう寝るね
- 【実況】博衣こよりのえちえちカービィのエアライダー🧪★2
- 最近気付いたんだけど俺肉の味じゃなくて塩味と食感で米食ってた
- 【高市速報】日本人の3割「中国への武力行使に踏み切る必要がある」ANN世論調査 [931948549]
