Лишние NOPs и ветви в неоптимизированном MSIL

Когда я компилирую следующий код в качестве отладки...

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 Инструкция генерируется.

1 ответ

Решение

Компилятор создает эти коды операций, чтобы обеспечить лучший опыт отладки. В начале каждой строки C# компилятор вводит nop поэтому отладчик может сломаться там. Ветвь и временная локальная переменная создаются для анализа возвращаемого значения функции.

Другие вопросы по тегам