2010-09-11 9 views
19

me di cuenta de que el compilador de C# genera una instrucción ret al final de void métodos:¿Se requiere una instrucción ret en las aplicaciones .NET?

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

He escrito un compilador para .NET y funciona sin importar si emiten una declaración ret o no (I' he comprobado el IL generado y de hecho no está allí).

Me pregunto: ¿Es ret en métodos que requieren void requerido para algo? Parece que no hace nada con la pila, por lo que creo que es completamente innecesario para los métodos void, pero me gustaría saber de alguien que sepa un poco más sobre el CLR.

+0

(supongo que el C# chicos emiten RET en el método de vacío becuase que hace que su trabajo sea más fácil: sólo tiene la función de un generador de métodos en su compilador que se utiliza para los métodos y sin efecto y no vacíos solo siempre emite ret en lugar de verificar si es necesario. Aunque estoy adivinando) –

+0

podrías usar el reflector .NET para ver si genera un bytecode diferente. Mi conjetura es absolutamente no, porque no hay ninguna razón para ello. La suposición que mencionas en tu comentario también se ve bien. –

+0

@Merlyn No, no es así. Si no emito ret, no se emite ret en el IL. –

Respuesta

22

Según el C# Standard (ECMA-334), un método se define como la siguiente:

A method is a member that implements a computation or action that can be performed by an object or class. Methods have a (possibly empty) list of formal parameters, a return value (unless the method’s return-type is void), and are either static or non-static.

(ECMA-334; 8.7.3: Métodos).

Ahora, la CLI estándar define lo siguiente:

Control is not permitted to simply “fall through” the end of a method. All paths shall terminate with one of these instructions: ret, throw, jmp, or (tail. followed by call, calli, or callvirt).

(ECMA-335; 12.4, 6)

Esto significa, que en C#, un método de regresar void no necesita una instrucción de retorno. Sin embargo, como el compilador de C# compila el código de C# para el código de IL, que requiere una terminación de ruta al final de un método, emite un ret para finalizar el método.

17

De hecho es necesario para que el código sea verificable. De lo contrario, PEVerify mostrará el siguiente mensaje de error:

[IL]: Error: [(filename) : (methodname)][offset 0x00000000] fall through end of the method without returning

8

De Ecma-335. (12.4, 6)

Control is not permitted to simply “fall through” the end of a method. All paths shall terminate with one of these instructions: ret, throw, jmp, or (tail. followed by call, calli, or callvirt).

+2

Ecma-355 se titula 'Túnel de QSIG sobre SIP' –

+0

¡Uy! Bien manchado. –

Cuestiones relacionadas