[過去ログ] C#, C♯, C#相談室 Part96 (1002レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
152
(2): デフォルトの名無しさん (ワッチョイ 1232-IMun) [sage] 2022/03/15(火) 23:25:37.07 ID:ZTE9InWz0(3/3) AAS
>>149
149(1): デフォルトの名無しさん (ワッチョイ a236-8qwV) [sage] 2022/03/15(火) 22:07:11.34 ID:uT8cdwkS0(4/4) AAS
>>145
そうですね。アドバイスありがとうございます。

私はこれまでこの手の問題は「まずは自分を疑え」と教わってきて
実際それで大抵の問題は解決してきたのですが、
皆様のお話をうかがうに、今回は自分の勘違いではなく
よそに原因があると考えたほうがいいのかもしれません。

これまで報告等は経験がないのですが、
それも視野に入れて調べてみたいと思います。

>>146
勉強になります。
その特殊な最適化で結果が変わることがバグなのか
私の力では判断が難しそうなのが歯がゆいところです。

>>147
> そう、片方が0なら実質意味はないから加算命令が現れなくても不思議ではないけど
> Console.WriteLine(x);としてみても固定アドレス0をデリファレンスするので
私の理解不足で、
「片方が0なら実質意味はない」 ← 0 + p の計算は必要ない?そりゃそうだ!
「固定アドレス0をデリファレンスする」 ← 0 + p = 0 ということ?p ではなくて?
という感想を持ってしまいました。
申し訳ないのですが、もしよろしければもう少し詳しく説明していただけないでしょうか。

> C#的には未定義なら未定義でビルド時か実行時にエラーを出しそうだけど
> Unsafeでチェックされないのか判断に困る。さもなければ最適化のバグだと思う
ご意見どうもありがとうございます。とても共感させていただきました。
未定義であればこそデバッグ時に教えてほしいものですが、
実際にはデバッグ時には期待通りに動作してしまうのが厄介なところです。
件の部分はJITコンパイルされたマシンコードの話で、ref intを参照する際に
xからでなくても「mov ecx, dword ptr [ptr]」的であっても整合性は取れるが
逆アセが「mov ecx, dword ptr [0]」になるので、xはnullにされてるという話

それならばIsNullRefが消えるのは順当としても、xがnullになる代入の欠落が
NullRef<int>が宜しくないのか、それをAddByteOffsetに与えるのがダメなのか
単なるバグか…、Unsafe.AsRefに直接IntPtr渡せれば/unsafeとせず済むのにね
153
(2): デフォルトの名無しさん (ワッチョイ a236-8qwV) [sage] 2022/03/16(水) 00:04:15.38 ID:pAqxvPky0(1/2) AAS
>>151
151(1): デフォルトの名無しさん (ワッチョイ ed2f-lWiN) [sage] 2022/03/15(火) 22:47:23.94 ID:BlmPXv890(2/2) AAS
そもそも値型にたいするヌル参照が未定義な気がするが
最適化で数値ゼロとヌル参照が同一視されてるとか?
なるほど…。
ただ、Unsafe.IsNullRef(ref Unsafe.NullRef<int>()) と書けてこれが true を返すので、
値型に対するヌル参照が定められていない場合は Unsafe.NullRef<T> の T に int が
指定できること自体がバグということになってしまうような気もします。
一応未定義ではないけど、CLR 外部との相互利用等で必要に迫られない限り
使ってくれるなという感じなのでしょうか。

>>152
ご親切に説明していただきどうもありがとうございます。
逆アセンブルの結果に “なぜだか理由は分からないが” 0 になっている部分があって、
そこから x が null にされているというという事実が読み取れる、ということですね。
(まだ間違っていたら大変申し訳ありません)

> NullRef<int>が宜しくないのか、それをAddByteOffsetに与えるのがダメなのか
NullRef<T> と AddByteOffset<T> のソースコードのコメントにはそれぞれ

ldc.i4.0
conv.u
ret

ldarg.0
ldarg.1
add
ret

とあって、これを見る限り、NullRef<int>() を AddByteOffset<int> に与えることの問題は
私には読み取れませんでした。
(そもそもこの問題で IL を持ち出すこと自体が見当外れなのでしょうか)
もちろん、実際には特殊な JIT 最適化が行われているのでしょうが、
その結果 IL から期待される動作と変わってしまうようなら、
やはりバグとして報告したほうがよいのかなというのが今のところの考えです。
154
(1): デフォルトの名無しさん (ワッチョイ a236-8qwV) [sage] 2022/03/16(水) 00:10:04.98 ID:pAqxvPky0(2/2) AAS
>>152
> Unsafe.AsRefに直接IntPtr渡せれば/unsafeとせず済むのにね

そうなんです!というか、本来私がしたいことからいうと
MemoryMarshal.CreateSpan<int> メソッドに IntPtr 型を渡せると一番よいのですが、
それができないのでこのメソッドが受け付けてくれる ref int を作るという方向で考えています。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.041s