int32
を64ビットnative int
に追加する場合、CLRは32ビット整数の符号拡張またはゼロ拡張を行いますか?そして最も重要なのは、どの情報に基づいてこの選択をするのか?64ビットのネイティブintにint32を追加した結果は?
私は.NETコンパイラを書いていますし、徹底的にECMA仕様を読んだが、答えを見つけることができませんでした。 int32
、int64
、及びnative int
:
はCLIは、その評価スタック上に格納された値に、その操作にこれらのタイプのサブセットのみをサポートします。
からECMA 335、セクションIは12.1:のための1:サポートされているデータ型
評価スタック上の値はその符号の有無についての情報、オペランドの符号の有無は、2つのバリエーションを持っている問題ではそのための手順を持っていないので、 1つは符号なし整数です。オーバーフローをチェックしない命令は、オペランドが同じサイズである限り、オペランドの符号性を気にする必要はないので、単一のバリアントしか持たない。ただし、オペランドが常に同じサイズではない...
ECMA 335、セクションIII 1.5:オペランドタイプテーブル状態int32
とnative int
が減算、添加することができる、乗算と分割。結果は再びnative int
です。 64ビットシステムでは、native int
は64ビット幅です。
ldc.i4.0 // Load int32 0
conv.i // Convert to (64-bit) native int
ldc.i4.m1 // Load int32 -1
add // Add native int 0 and int32 0xFFFFFFFF together
ここで結果はどうなりますか?この仕様によれば、実行時には、スタック上の値の正確な型または符号付きを追跡する必要がないことに注意してください。int32
,int64
およびnative int
(およびここでは関係のないもの)のみが分かります。
それは内部的にネイティブint型として表現されているので、私はまた、追加のこの種を使用することになり、そのIntPtr
とUIntPtr
算術を想像。ただし、ILSpyは、IntPtr
とInt32
をC#で追加すると、IntPtr
クラスのオーバーロードされた+演算子が呼び出され、符号付きInt32
引数のみを受け付けることが示されています。
CILで直接実行すると(add
命令を使用)、整数が符号付きとして解釈されます。 Monoでも実装されているはずですが、私の知見を裏付ける参考文献は見つかりませんでした。
昇格された値の記号は捕捉されません。可能な解決策については、この情報を参照してください(Macの場合ですが、この場合は問題ありません):https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/64bitPorting/MakingCode64-BitClean/MakingCode64- BitClean.html – K3N