Что делает заявление if
, когда оно скомпилировано в IL?Что такое if, если смотреть в IL?
Это очень простая конструкция в C#. Может ли кто-нибудь дать мне более абстрактное определение того, что это на самом деле?
Что делает заявление if
, когда оно скомпилировано в IL?Что такое if, если смотреть в IL?
Это очень простая конструкция в C#. Может ли кто-нибудь дать мне более абстрактное определение того, что это на самом деле?
Вот несколько if
заявления, и как они переводят к IL:
ldc.i4.s 0x2f var i = 47;
stloc.0
ldloc.0 if (i == 47)
ldc.i4.s 0x2f
bne.un.s L_0012
ldstr "forty-seven!" Console.WriteLine("forty-seven!");
call Console::WriteLine
L_0012:
ldloc.0 if (i > 0)
ldc.i4.0
ble.s L_0020
ldstr "greater than zero!" Console.WriteLine("greater than zero!");
call Console::WriteLine
L_0020:
ldloc.0 bool b = (i != 0);
ldc.i4.0
ceq
ldc.i4.0
ceq
stloc.1
ldloc.1 if (b)
brfalse.s L_0035
ldstr "boolean true!" Console.WriteLine("boolean true!");
call Console::WriteLine
L_0035:
ret
Одна вещь, чтобы отметить здесь: инструкции IL всегда «противоположен». if (i > 0)
означает что-то, что эффективно означает «если i <= 0
, а затем перепрыгнуть через тело блока if
».
Ошибка копирования-вставки в куске, начиная с L_0020: повторение ltc.i4.0, затем ceq? –
@AndyDent Нет, это точный результат работы компилятора. Вы можете утверждать, что он может быть написан короче, но если вы просто удалите один 'ldc.i4.0' +' ceq', значение изменится: тогда оно будет означать 'i == 0' вместо' i! = 0 '. – Timwi
понял! (Я думаю), в большой форме, что ИЛ эквивалентен b = ((i == 0) == 0) –
Это зависит от состояния if
. Например, если вы проверяете ссылку на null
, компилятор выдает команду brfalse
(или brtrue
в зависимости от того, что вы написали).
фактическогоif
условия будет отличаться в зависимости от самого состояния, но в dissasembler как ILDASM
или отражатель будет лучшим инструментом для изучения более.
Простой пример:
ldloc.1 // loads first local variable to stack
ldc.i4.0 // loads constant 0 to stack
beq // branch if equal
Это было бы равно
if(i == 0) //if i is the first local variable
Другие МФС будут отличаться, в том числе условных ветвей. Это слишком сложно объяснить в одном посте, вам лучше искать введение в IL-Code.
Существует хорошая статья на codeproject относительно этого.
Используется инструкция перехода, которая будет переходить к целевой команде в зависимости от значения (ов) в верхней части стека.
brfalse Branch to target if value is zero (false)
brtrue Branch to target if value is non-zero (true)
beq Branch to target if equal
bge Branch to target if greater than or equal to
bgt Branch to target if greater than
ble Branch to target if less than or equal to
blt Branch to target if less than
bne.un Branch to target if unequal or unordered
Вы можете проверить это с помощью 'ildasm.exe' из командной строки Visual Studio. –
Это очень простая конструкция, период. Я не знаю в IL, но в коде сборки вы выполняете сравнение, а затем ветку. Очень просто в asm, поэтому нужно предположить, что он так же прост в языке высокого уровня. – Jonathan
На ваш вопрос ответили утверждением этого вопроса ранее. http://stackoverflow.com/questions/3659093/ms-c-compiler-and-non-optimized-code/3660295#3660295 –