結局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/
222デフォルトの名無しさん
垢版 |
2023/04/17(月) 11:17:37.21ID:IM/7VFpy
ほんと低次元
小学校低学年のけんか
2023/04/17(月) 11:52:45.49ID:kmcXsww3
>>221
解決しました
ほんとうにありがとうございました
2023/04/17(月) 12:02:11.37ID:Dh5lk+HW
いつまでたっても安定化しないBtrfsを先にRustで完全実装してみせるくらいの実績を出してみやがれってんだ
2023/04/17(月) 15:31:33.55ID:GdiItcWS
質問です
例えば画像データの上下反転をしたい場合
let ppix: *mut std::ffi::c_void = im.pixels;
const W: usize = 640;
const H: usize = 480;
const D: usize = 24;
let q = ppix as *mut [[u8; W * D / 8]; H];
for j in 0..h/2 {
let t: [u8; W * D / 8] = (*q)[(h - 1 - j) as usize];
(*q)[(h - 1 - j) as usize] = (*q)[j as usize];
(*q)[j as usize] = t;
}
で実際に可能だったのですが W, H, D を固定にしたくなくて(続く)
2023/04/17(月) 15:32:27.02ID:TZ1fhzdQ
ファイルシステムのようなクリティカルな用途で使うわけないだろ
2023/04/17(月) 15:36:19.73ID:GdiItcWS
let ppix: *mut std::ffi::c_void = im.pixels;
let pitch: usize = im.pitch as usize; // im.pitch: std::ffi::c_int (値はほぼ3)
for j in 0..h/2 {
let a: usize = j as usize * pitch;
let p: *mut u8 = (ppix as usize + a) as *mut u8;
let b: usize = (h - 1 - j) as usize * pitch;
let q: *mut u8 = (ppix as usize + b) as *mut u8;
let mut btm = std::slice::from_raw_parts_mut(p, pitch);
let mut top = std::slice::from_raw_parts_mut(q, pitch);
let mut t: Vec<u8> = vec![0u8; pitch];
t.copy_from_slice(top);
top.copy_from_slice(btm);
btm.copy_from_slice(&t);
}
の様に書き換えて h は可変 w と d は pitch に置き換えで
こちらも動作はするのですがコードが冗長になってしまっています
後者をもう少しすっきりさせたいのですがどんなやり方が考えられますか?
2023/04/17(月) 15:45:58.71ID:uD1jGkf7
なんでレスバスレで質問してんの?
229デフォルトの名無しさん
垢版 |
2023/04/17(月) 15:56:57.46ID:jycfg89f
>>220
お前がC++の知識が全く無いことが分かった
批判をするなら勉強しなさい
2023/04/17(月) 16:18:46.99ID:Q4jLO7Eu
>>225
ちゃんと動くかは分からん

chunks_exact_mut, rchunks_exact_mutの仕様だとhが奇数でも問題ないはず

fn main() {
let mut ppix = vec![0u8; 640 * 480 * 24];
let pitch = 640 * 24;
let h = 480;
// ↓この辺から参考に
let (top, bottom) = ppix.split_at_mut(pitch * h / 2);
for (top_chunk, bottom_chunk) in top
.chunks_exact_mut(pitch)
.zip(bottom.rchunks_exact_mut(pitch))
{
top_chunk.swap_with_slice(bottom_chunk);
}
}
2023/04/17(月) 16:23:53.42ID:HKDHATFA
>>228
レスバはレスバしたい奴に任せてほっとこうぜ
結局Rustも使うC++erが参考になる質問なら見学しとくから
でも質問スレとかないんかな
2023/04/17(月) 16:28:57.08ID:ToGc2WrC
>>229
安全にするために「C++でも所有権の理解とスマポ利用は避けることができない」で合っとるやろ
まさか自分で管理してdeleteすればいいから不要と言い出すんじゃないだろうな
2023/04/17(月) 16:45:26.70ID:lV//RKk9
let ppix: *mut std::ffi::c_void = im.pixels;
let pitch: usize = im.pitch as usize;

for j in 0..h/2 {
let a = j * pitch;
let p: *mut u8 = (ppix as usize + a) as *mut u8;
let b = (h - 1 - j) * pitch;
let q: *mut u8 = (ppix as usize + b) as *mut u8;

let btm = std::slice::from_raw_parts_mut(p, pitch);
let top = std::slice::from_raw_parts_mut(q, pitch);

for k in 0..pitch {
std::mem::swap(&mut btm[k], &mut top[k]);
}
}
2023/04/17(月) 17:12:38.63ID:KX4+3zuW
>>230
let len: usize = h as usize * pitch;
let (top, bottom) = std::slice::from_raw_parts_mut(ppix, len).split_at_mut(len / 2);
で動作しましたありがとう
2023/04/17(月) 18:39:30.36ID:PUaqCjxF
数学とは
実験データに基づかない証明ばかりしているくせになぜか正しい
現実の影響を受けにくい

前例がなければ何もしなかったのに
実例を見るとついつい行動してしまう模倣犯みたいな感じになりにくい
2023/04/17(月) 19:11:10.94ID:RKcegE7f
>>208
Rustc の指示通りに修正すると余計にエラーが増えて
状況が悪化して散々振り回されて時間を無駄にする
結局指示と違う修正ですっきり治ることも多い
2023/04/17(月) 19:14:33.38ID:RKcegE7f
時々的外れな事言ってくるのも ChatGPT と良い勝負
2023/04/17(月) 19:19:30.04ID:rguxj2m5
最初に&mut [u8]スライスを作るところだけffiサイドに分離しておくのがよいね

>>236
どういう不備があるかの本質をエラーメッセージはまず示してくれている
その補助としてコンパイラが一案を示してくれているから自分の望む案でなくてもエラーの理解に助かる
時間の節約にこそなれど無駄にすることはない
もし時間を無駄にしているなら本質を無視しているバカさを自白してるようなもの
2023/04/17(月) 20:41:01.82ID:DvspYu3R
時間を無駄にしたのが本人とは限らんだろ
2023/04/17(月) 21:07:11.98ID:jycfg89f
>>232
もし>>213>>220とレスを返すのを肯定するとしたら
お前もC++の知識が文字通り皆無なのだと分かる

class Hoge {
public:
void *operator new (size_t p) = delete;
};
2023/04/18(火) 04:15:46.41ID:iA5+Rtnt
>>212 >>216
unsafe で隠蔽してるだけで
Java の Exception みたいに上位にも伝播する訳でもないのに
全体としては安全が確保されてるとか
夢観過ぎ自己満でしかない

問題先送りどころか隠蔽体質
242デフォルトの名無しさん
垢版 |
2023/04/18(火) 04:46:00.70ID:hIfvNlZE
握り潰しの握りっ屁でも臭わないのがRustの美学
2023/04/18(火) 06:13:08.68ID:MLRxBRH/
>>241
全くの逆
むしろ例えば生ポインタによる読み書きアクセスがunsafeなように一番下はunsafeに行き着く
しかし例えばある条件を伴ってそのメモリ領域が確保された安全なアクセスであると保証できる状況を満たす場合は
そのアクセス関数をsafeなインタフェースとして提供できる
大雑把な違いは以下

【C++の場合】
プログラム全体にunsafeが散らばっていてプログラム全体がunsafe
つまり人間がプログラム全体に対してその安全性を保証しなければならない

【Rustの場合】
safeなインタフェースの中にunsafeが閉じ込められている
その閉じ込める部分に対してのみ人間が安全性を保証しなけれはならない
プログラム全体の安全性はコンパイラが保証できる仕組み

例えばC++の場合は生ポインタでなく参照を使っている場合でもダングリング発生の危険があるのに対して
Rustの参照はライフタイムが管理されてダングリングが発生しないとともにデータ競合防止アクセスも保証される
さらに他のスレッドと共有できるか否かも含めて型付けと静的型チェックによりコンパイル時に安全性を保証できる言語仕様となっている
2023/04/18(火) 07:00:27.77ID:DviFuO26
OOP的な隠蔽だろ?

まあ俺のは素人が書いてるコードだし、自己満と言われようと構わんがなw
そして、そういう用途・運用もあるんだ
ガチプロばっかりが、PC・マイコン使ってない
2023/04/18(火) 08:26:30.53ID:Dh7Xhf9O
気軽に聞かせて
unsafeが残っていながら なにが安全じゃ! っていう反駁をちょくちょく見るけど、
unsafeが要らないようなプロセッサってほんとに作れないもんかな

絵空事じゃないぞ、FPGAにオレオレ プロセッサって起こせるようになったらしいし
RustBeltに載ってるのかな(読破はできてない
2023/04/18(火) 09:15:43.87ID:NALS/zAj
そろそろ貼っとくか
safeでもメモリはぶっ壊せる
https://speakerdeck.com/moratorium08/rustfalseunsound-hole-issue-number-25860woli-jie-suru
2023/04/18(火) 09:50:26.33ID:tfRpsuLy
相関関係ではなく因果関係を立証できる者だけが
safeでも原因になれることを立証できる
2023/04/18(火) 10:16:01.43ID:sxhvE7iU
>FPGAにオレオレ プロセッサって起こせる
何十年も前から可能だったよ
っていうか原理的に出来て当たり前だし
「実用的な」って意味ならまあ色んな考え方もあるだろうが
249デフォルトの名無しさん
垢版 |
2023/04/18(火) 10:27:05.42ID:PTyVVN9Y
限りある脳のリソースをどこに使うかという極々当たり前のことだろ
それすらわからないようなやつがまともにプログラミングできる訳がないんだから何を言っても時間の無駄だよ
2023/04/18(火) 10:31:04.41ID:Dh7Xhf9O
まともじゃないヤツをプログラミングから排除するのがsafeか
こりゃこまったなww
2023/04/18(火) 10:43:23.90ID:tfRpsuLy
人を説き伏せる目的で言うのは時間の無駄だけど自分が言いたいことを言うのはいいんだよ
252デフォルトの名無しさん
垢版 |
2023/04/18(火) 11:43:26.04ID:rPAFEI4Z
なるほど
言いたいことを言う場がない人たちだから
こんなところで承認欲求剥き出しの長文書くのか
2023/04/18(火) 12:02:59.09ID:Dh7Xhf9O
試金石と思ってるところはあるな 大間違いならツッコミがあるし
自分も、まあそうかな、くらいなら、いちいち「そうだそうだ」って書かないしね
2023/04/18(火) 12:20:54.75ID:NALS/zAj
>>236
経験的にだけど、ライフタイム関連のヒントは真に受けない方がいい気がするな

多分、構造体や関数の定義側のライフタイムが意図通りにできていない場合に、そっちを直せというヒントを出せないのだと思う
定義を正としてそこから導出されるライフタイムや境界をひたすら書けと言うだけ
そんなヒントにハイハイと従ってるとそこら中ライフタイムパラメータまみれにされた挙げ句、最終的にlifetime conflictで二進も三進もいかなくなったことがある
結局その件はある関数の引数に2個ある参照のライフタイムパラメータの省略をやめて'a,'bに分けるだけでよかった記憶

あと'aで受け取りたいのに「'staticにすることを検討してください」とかもよく見る役立たずヒント
2023/04/18(火) 13:25:41.34ID:tfRpsuLy
グローバル変数をやめろと指示された → ヒープを使った → メモリが壊れた
という長期的な流れもあるので
'staticを検討することは指示を信じているとも言えるし、最初の指示を全力で疑っているとも言える
2023/04/18(火) 19:54:50.00ID:+ox+01C9
>>254-255
ほんそれ
2023/04/18(火) 20:52:44.33ID:qWAcGwU9
コンパイラのエラーメッセージを見ずにヒントだけを見るようなバカは
他のことでも重要部分を見ずに枝葉だけを見て失敗してきているんだろうな
2023/04/18(火) 22:19:21.28ID:NALS/zAj
いやーすんませんねバカで
実際ライフタイム系エラーメッセージって他のエラーに比してかなり分かりづらいと思うんだけど、読み方のコツとかあったら教えてくれませんかね?
2023/04/18(火) 22:56:45.81ID:1GQDyAx6
OOP言語のクラスと同じ感覚で構造体のフィールド組むとライフタイムのトラブルに嵌る気がする
Rustの構造体は一緒に使うデータというより一緒に捨てるデータのイメージだから
ライフタイム無しの構造体:データベースのテーブルのレコード
ライフタイム有りの構造体:↑を参照するビューのレコード
みたいな設計を意識するといいかも(RDBほど正規化を気にする必要はない)
こうするとビューが参照するテーブルごとにライフタイムパラメータが存在する形になる
あくまで個人の考え方というか経験論だから参考程度に
2023/04/19(水) 00:20:32.62ID:s8p2Q+oA
教師ありでも教師なしでも遅かれ早かれ同じ道を通りそうな方向に行く
教師ありの場合にしか通らない所で過学習しない
2023/04/19(水) 00:45:23.08ID:d1nAuXLd
>>259
スクリプト言語から来たんだけど
これまでなんでも連想配列に突っ込んでいたのが
実はアクセス毎にハッシュ値を計算して、ハッシュテーブルの衝突比較をして、ようやくたどり着くのを実感しちゃった
基本的にVecで持っていて、テーブルを引かなければならない時だけ使うHashMapを持つのがいいのかな
2023/04/19(水) 09:43:31.13ID:4c9fSoSa
>>246
狙ってできるということは、ぼーっとしてると踏むかもしれないってことだよな?

ライフタイムは銀の弾丸だ! みたいに、お題目のように言ってくるコピペへの反論として、
ちゃんと書かなきゃいけない、の主戦場がライフタイムの記述に移っただけじゃんってことでおっけー?

うんでも、template<> に近い感覚を覚えた、親しみを覚えたかな
はやくC++にも来ればいいのに
2023/04/19(水) 10:00:52.83ID:oanEffOH
普通に使われない書き方を恣意的に作らないと起きないため
実害なしとして放置となっている
2023/04/19(水) 10:08:03.97ID:4c9fSoSa
別にいいよ、放置で
でもそれを、(コピペ勢がいうような)安全っては言わない

俺は正確に、どう安全か知って使いたいんだ

C++だって、「そんな書き方すんなよ」ってのを踏むヤツが後を絶たない
だから、「書きようが悪いだけ」なんて反論が出るわけだ
2023/04/19(水) 10:31:19.03ID:vWGdqQhB
C++は初心者が自然に間違えて踏んでしまう
慣れているプロですら複雑化したときには間違えて陥ってしまう
そして現実に何度も何度も何度もプロたちがミスってきたからMicrosoftやGoogleなどIT大手も匙を投げ始めた

そのRustの件は初心者が間違えて踏んでしまうことは決してなく
慣れているプロが複雑化したときもそんな状況に陥ることはない
強引に恣意的にそれを目指して作り出さないと生じない
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のみ使えば書いたコードの安全性が保証される
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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