Требуется ли инструкция ret в приложениях .NET? - PullRequest
19 голосов
/ 12 сентября 2010

Я заметил, что компилятор C # генерирует инструкцию ret в конце void методов:

.method private hidebysig static void Main(string[] args) cil managed
{
    // method body
    L_0030: ret 
} 

Я написал компилятор для .NET, и он работает независимо от того, выдает ли яret утверждение или нет (я проверил сгенерированный IL, и его там действительно нет).

Мне просто интересно: ret для методов, возвращающих void, требуется для чего-либо?Похоже, он ничего не делает со стеком, поэтому я считаю, что это совершенно не нужно для void методов, но я хотел бы услышать от кого-то, кто знает немного больше о CLR?

Ответы [ 3 ]

22 голосов
/ 12 сентября 2010

В соответствии со стандартом C # (ECMA-334) метод определяется следующим образом:

Метод - это элемент, который реализует вычисление или действие, которое может быть выполнено объектом илиучебный класс.Методы имеют (возможно, пустой) список формальных параметров, возвращаемое значение (если тип метода не имеет значения void) и являются статическими или нестатическими.

( ECMA-334 ; 8.7.3: Методы).

Теперь стандарт CLI определяет следующее:

Управлению не разрешается просто «провалиться» через конецметод.Все пути должны заканчиваться одной из следующих инструкций: ret, throw, jmp или (tail. Затем call, calli или callvirt).

( ECMA-335 ;12.4, 6)

Это означает, что в C # методу, возвращающему void, не требуется оператор return.Однако, поскольку компилятор C # компилирует код C # в код IL, который требует завершения пути в конце метода, он выдает ret для завершения метода.

17 голосов
/ 12 сентября 2010

Это действительно необходимо для проверки кода. В противном случае PEVerify выведет следующее сообщение об ошибке:

[IL]: ошибка: [(имя файла): (имя метода)] [смещение 0x00000000] провалиться до конца метода без возврата

8 голосов
/ 12 сентября 2010

от Ecma-335.(12.4, 6)

Управлению не разрешается просто «проваливаться» через конец метода.Все пути должны заканчиваться одной из следующих инструкций: ret, throw, jmp или (tail. Затем call, calli или callvirt).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...