Следующая функция С#:
T ResultOfFunc<T>(Func<T> f)
{
return f();
}
неудивительно компилирует это:
IL_0000: ldarg.1
IL_0001: callvirt 05 00 00 0A
IL_0006: ret
Но эквивалентная функция F #:
let resultOfFunc func = func()
компилируется:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: tail.
IL_0005: callvirt 04 00 00 0A
IL_000A: ret
(Оба режима находятся в режиме освобождения). В начале есть дополнительный nop, который мне неинтересно, но интересная вещь - дополнительные инструкции ldnull
и tail.
.
Мое предположение (возможно, неверное) заключается в том, что ldnull
необходимо, если функция void
, поэтому она все равно возвращает что-то (unit
), но это не объясняет, что является целью tail.
инструкция. И что произойдет, если функция действительно толкает что-то в стеке, не застрял ли он с лишним нулем, который не появляется?