stelemの動作
Nemerleコンパイラの不具合でbyte配列に対する代入なのにint配列としてしまっているコードがありました。ILコードを見てみたんですが、stelem命令って領域が足りなくても落ちたりしないんですね・・・
.assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89) .ver 2:0:0:0 } .assembly 'hello' { .ver 0:0:0:0 } .module 'hello' .class private abstract auto ansi sealed Hello extends [mscorlib]System.Object { .method private hidebysig static void Main() cil managed { .entrypoint .locals init (uint8 V_0) .maxstack 3 /* byte bs = new byte [5] */ ldc.i4.5 newarr [mscorlib]System.Byte stloc.0 /* byte型配列のインデックス1を int型配列のインデックス1としてアクセス */ ldloc.0 ldc.i4.1 ldc.i4.s 0xf00f stelem.i4 // stelem.i1 /* bs[4]の値が書き換わっている */ ldloc.0 ldc.i4.4 ldelem.u1 box [mscorlib]System.Byte call void [mscorlib]System.Console::WriteLine(object) ret } }
byte配列は5バイト分しか確保していないのに、int配列のインデックス1にアクセスしてもエラーになりません。領域に入る分だけ格納され、残りは切り捨てられます。上記の場合、0xf00fの上位バイトが捨てられ、結果は15になります。てっきり、実行時エラーかメモリ破壊を起こすと思ってました。