2

次のコードをデバッグとしてコンパイルすると...

public class MyClass
{
    private int myField;

    public int MyProperty
    {
        get { return myField; }
        set { myField = value; }
    }
}

...一見役に立たない命令を含む奇妙なバイトコードがコンパイラによって生成されます。たとえば、プロパティのゲッター用に生成されるものを参照してくださいMyProperty( で逆アセンブルildasm.exe):

.method public hidebysig specialname instance int32 
        get_MyProperty() cil managed
{
    // Code size       12 (0xc)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000)
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  ldfld      int32 MSILTest.MyClass::myField
    IL_0007:  stloc.0
    IL_0008:  br.s       IL_000a
    IL_000a:  ldloc.0
    IL_000b:  ret
} // end of method MyClass::get_MyProperty

具体的には、そこで何nopをしているのIL_0000ですか?そして、なぜコンパイラは文字通りどこからともなくこの役に立たないbr.s命令を生成するのでしょうか? IL_0008一時的なローカル変数を作成するのはなぜCS$1$0000ですか?

リリース構成の場合、命令セットは期待どおりに生成されます。

IL_0000:  ldarg.0
IL_0001:  ldfld      int32 MSILTest.MyClass::myField
IL_0006:  ret

編集

なぜブランチと一時的なローカル変数が別の質問にあるのかという質問に対する答えを見つけたと思います。おそらく、デバッグ中にブレークポイントを簡単に設定するためです。したがって、残っている問題は、nop命令が生成される理由です。

4

1 に答える 1