[過去ログ] Rust part16 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
685: 2022/09/10(土)14:31 ID:/uHulLcW(1) AAS
Rustすれのレベルの低さにガッカリ
Python質問すれとかみたいに和気あいあいとしてない殺伐にドッキリ
686(1): 2022/09/10(土)14:56 ID:qBfKxAEz(2/4) AAS
>>675みたいに書いた場合
>let mut bitmap:[u32; LEN] = [0; LEN];
のmutが余計だと警告が出る。この場合実際に確保されるメモリ領域は書き込みも出来るスタックフレームだろうし
mutを取っても動作上は問題ないと思うけど、mutがない領域に書き込むことになりプログラムの意味としては誤っている
参照先を強制的に書き換えるようなコードを書くと、とコードと警告と動作のミスマッチが起きる気がするけど
なんか上手い書き方はないのだろうか
この辺の低レイヤーの用途で参照先を書き換える話ってBookのReferenceやUnsafeあたりにもそれっぽい事書いてないし
どこを見たらいいのか判らない
687(2): 2022/09/10(土)15:47 ID:BhJh8aSd(2/5) AAS
>>675
ARGB32にDefault実装して
let mut bitmap : [ARGB32; LEN] = Default::default();
とするのが良いかと
repr(C)がついてない構造体のメモリ上での表現がどうなるかは保証されてないから元のコードが意図通り動作する保証はないと思う
688(1): 2022/09/10(土)15:48 ID:vDnMZIxl(1) AAS
>>675
初期化難しいかな。こうとか
外部リンク:play.rust-lang.org
689: 2022/09/10(土)15:54 ID:BhJh8aSd(3/5) AAS
>>687
[T; N] は N <= 27 までしかDefault実装されてなかったからこのコードじゃダメだった
こっちならOK
let mut bitmap: [ARGB32; LEN] = std::array::from_fn(|_i| Default::default());
690: 2022/09/10(土)16:11 ID:sOVkY8n5(1) AAS
最後の手段のtransmuteは安易に使うものじゃないと思う
691(1): 2022/09/10(土)16:39 ID:qBfKxAEz(3/4) AAS
>>687
すみません。構造体にはrepr(packed)を付けています。u8がパディング無し4つ並ぶはず
repr(C)だとCと同様にパディングされる可能性が出てくると思うのですが
>>688
CloneとCopyを付ける方法に関してはどのような動作になるのか確信を持てていないです
原則コピーになるという情報は出てきますが、画像のバッファだし原則参照で必要なときだけ
コピーしたいです(すでに初期化とは別のところで問題になっています。参照とコピーの
切り替え方法が判らない)
692(1): 2022/09/10(土)18:12 ID:n3Y/KVD/(1) AAS
>>686
最初に定義した変数bitmapはmoveしてるだけだからmutは余計でいいと思うけど?
693(2): 2022/09/10(土)19:24 ID:qBfKxAEz(4/4) AAS
>>692
自分の理解があっているか不安なんですが、mutを付けずにletで宣言すると書き換わらない値として
書き込めないメモリ領域(例えば.textセクション)に配置されたりしないのか?というのが心配な点です
言語仕様上mutを付けない宣言でも必ず読み書き可能な領域に配置されるというのであればそれでかまわないと思いますが
とりあえず手元のx64向けのコンパイラではmutを付けずともスタックフレームに配置されるようですが
組み込み向けなど他のコンパイラでも同様の動作を前提として問題ないのか判りません
古いバージョンのBookにはスタックやヒープの解説があったようですが
外部リンク[html]:web.mit.edu
最新版にこのページはないような・・・しかも
>Rust ‘stack allocates’ by default, which means that basic values ‘go on the stack’.
省1
694: 2022/09/10(土)20:06 ID:xD3pa07u(1/2) AAS
let bitmap:[u32; LEN] = [0; LEN];
let mut bitmap:[ARGB32; LEN] = unsafe {core::intrinsics::transmute::<_, [ARGB32; LEN]>(bitmap)};
これでいいってことじゃない?
一個目のbitmapは実際書き込んでないからmut不要
二個目のbitmapは変数名同じだけど一個目とは別の変数で、こっちは次の行で書いてるからmut必要
695: 2022/09/10(土)20:13 ID:xD3pa07u(2/2) AAS
あぁ言いたいことは分かった
確かにtransmuteしてるからバックエンドの挙動によっては変なことになりうるかもね
ただそれは別にmutをつけても保証はされない気がする
696(1): 2022/09/10(土)20:24 ID:BhJh8aSd(4/5) AAS
>>691
repr(packed)を指定した構造体のフィールドへのアクセスは未定義動作を引き起こす可能性があるからrepr(packed)は基本的には使わない方が良いよ
外部リンク[html]:doc.rust-lang.org
確かにrepr(C)やrepr(Rust)はパディングされる可能性があるけど、フィールドのアラインメントを適切にするために必要なものなので
パディングが問題になるならフィールドのメンバーの順序やサイズを見直すか、フィールドの値を読むのに std::ptr::read_unaligned を使う必要があるよ
外部リンク[html]:doc.rust-lang.org
read_unalignedのドキュメントにも書いてあるけど、アライメントが不適切なフィールドへの参照を作るのすら未定義動作になるという落とし穴もあったり、
repr(packed)な構造体の取り扱いにはいろいろと注意が必要になるので、本当に必要なとき以外は使わない方が良いよ
あと、repr(packed)はrepr(packed, Rust)と同じ意味になるので、構造体のフィールドがメモリ上でどのような配置になるかの保証はないよ
フィールドの定義順とメモリ上での順序を同じにしたいのであれば repr(C) または repr(C, packed) と指定する必要があるよ
省3
697: 2022/09/10(土)20:36 ID:BhJh8aSd(5/5) AAS
>>693
let a = ...;
let mut a = a;
みたいに書いた場合、一個目のaと二個目のaは別の変数扱いでそれぞれ個別に領域が割り当てられるよ
二個目のaに格納されるのはaの値で、ポインタじゃないから一個目のaが書き込み不可な領域に格納されていたとしても
二個目のaのために割り当てられた読み書き可能な領域に一個目のaの値がコピーされるような動作になるはず
最適化によって一個目のaと二個目のaが同じ領域を使い回すようになるかもしれないけど、二個目のa定義後はその領域に対する書き込みは可能なことが保証されてるはず
transmuteを呼び出した場合も同じで、
transmute(a) という呼び出しをした場合transmuteに渡されるのはaの値なので、二個目のaの定義後は問題なくaに書き込めるはず
ただし、transmuteに&aを渡して&mutに変換するみたいなことをすると未定義動作になるから注意は必要
省2
698: 2022/09/11(日)12:51 ID:6axTKkj4(1) AAS
>>693
>mutを付けずにletで宣言すると書き換わらない値として
>書き込めないメモリ領域(例えば.textセクション)に配置されたりしないのか?というのが心配な点です
しねーよ。
組み込みだろーがそれは変わらない。
letついて束縛変数といわれようが変数は変数。
699: 2022/09/11(日)13:08 ID:3JeGkSLy(1/3) AAS
今はしないけどそうなるような最適化は禁止されてないのでは
700: 2022/09/11(日)13:49 ID:7UmicIsS(1) AAS
コンパイル時に値が確定してないとtextセクションに書けないでしょ
701: 2022/09/11(日)13:55 ID:VMVpvyTB(1/2) AAS
そっちは定数でconstだしそうなる
letはあくまでもimmutableな変数であり定数ではない
702: 2022/09/11(日)13:57 ID:kEOVMHNm(1) AAS
コンパイル時に確定するような式なら最適化でありえるんじゃないの?
703: 2022/09/11(日)14:07 ID:VMVpvyTB(2/2) AAS
どのように最適化されようが
constではなくlet x = ...ならば
let mut x = x; とムーブして書き換え可能
これは言語のレベルで保証される
そしてそのように使うならば最適化も無駄なことせずにtext segmentでなくdata segmentに置くだろう
704(1): 2022/09/11(日)14:40 ID:ujBIW69o(1/3) AAS
CloneとCopyについて
let mut bitmap:[u32; LEN] = [0; LEN];
let mut bitmap:[ARGB32; LEN] = unsafe {core::intrinsics::transmute::<[u32; LEN], [ARGB32; LEN]>(bitmap)};
と
#[derive(Clone, Copy, Default)]
&
let mut bitmap:[ARGB32; 16] = [ARGB32::default(); LEN];
で読み書きを
bitmap[0].red = 0x80;
let x = bitmap[0].red;
省10
705: 2022/09/11(日)14:49 ID:FOB38Q8d(1/2) AAS
そのような実装はしたくないわけですか
706: 2022/09/11(日)15:13 ID:/O1tQPyF(1/2) AAS
どの言語でも同じ
Rustでも&mutでtransmuteしてもendian依存は避けられないな
let mut x = 0x01020304_u32;
let a = unsafe { std::mem::transmute::<&mut u32, &mut [u8; 4]>(&mut x) };
a[1] = 7;
assert_eq!(x, 0x01020704);
とlittle endianでは7の位置はこうなる
707(1): 2022/09/11(日)18:54 ID:gEyGQ7vE(1) AAS
このスレでよく出てくる μt ってなんなん?
音的に mut をそう書いてる異常者がいるだけかと思ってるんだけど、なにか別の意味を持った概念や機能だったりするの?
708(2): 2022/09/11(日)20:25 ID:FOB38Q8d(2/2) AAS
自分も思ったけどブラウザによっては & mut がそうなるみたい
709: 2022/09/11(日)20:27 ID:QYXgEc7E(1) AAS
>>708
そうなんだ。
710: 2022/09/11(日)20:45 ID:hnVgjqVb(1) AAS
>>708
なるほど、ありがと。
異常者かと思って真面目に読む気が失せてたんだけど誤解だったか。
711: 2022/09/11(日)21:25 ID:zZ32ojSE(1) AAS
HTMLの文字参照で& muがμ
712(1): 2022/09/11(日)21:45 ID:ujBIW69o(2/3) AAS
例えば
pixel.alpha = in[0].alpha;
pixel.red = in[0].red / 2;
pixel.green = in[0].green / 2;
pixel.blue = in[0].blue / 2;
out[0] = pixel;
と
red = 0xFF & (in[0] >> 16);
green = 0xFF & (in[0] >> 8);
blue = 0xFF & in[0];
省9
713(1): 2022/09/11(日)21:47 ID:3JeGkSLy(2/3) AAS
>>704
パディングというかメモリアクセス時のアラインメントについてはCPUの仕様だから言語関係ないよ
x86がunalignedなアクセスについてゆるゆるだから忘れられがちだけど雑に書いたプログラムをarmで動かしたりするとクラッシュする
今回はu8へのアクセスだからさすがにパディング入れられることはないと思うけどね
714(1): 2022/09/11(日)21:50 ID:3JeGkSLy(3/3) AAS
>>712
シフト処理など隠蔽してくれるアクセサメソッド用意したらだいたい同じような読みやすさになるのでは
上下前次1-新書関写板覧索設栞歴
あと 288 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.026s