2010-09-11 20 views
19

tôi nhận thấy rằng các biên dịch C# tạo ra một hướng dẫn ret vào cuối void phương pháp:Có cần phải có hướng dẫn thử trong ứng dụng .NET không?

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

Tôi đã viết một trình biên dịch cho NET và nó hoạt động bất kể nếu tôi phát ra một ret tuyên bố hay không (tôi' đã kiểm tra IL tạo ra và nó thực sự không có trong đó).

Tôi tự hỏi: Có phải ret về phương pháp trả lại void cần thiết cho bất kỳ điều gì không? Nó dường như không làm bất cứ điều gì với chồng, vì vậy tôi tin rằng nó hoàn toàn không cần thiết cho phương pháp void, nhưng tôi muốn nghe từ một người biết nhiều hơn về CLR?

+0

(tôi giả sử C# kẻ phát ra RET vào khoảng trống phương pháp bởi vì nó làm cho công việc của họ dễ dàng hơn: Chỉ có chức năng một phương pháp-phát trong trình biên dịch của họ được sử dụng cho các phương pháp vô hiệu và không void và chỉ cần luôn luôn phát ra thay vì kiểm tra nếu nó cần thiết. Tôi chỉ đoán mặc dù) –

+0

bạn có thể sử dụng. NET phản xạ để xem nếu nó tạo ra bất kỳ bytecode khác nhau. Đoán của tôi là hoàn toàn không, bởi vì không có lý do cho nó. Đoán bạn đã đề cập trong bình luận của bạn cũng đúng. –

+0

@Merlyn Không, không. Nếu tôi không phát hiện ra, không có ret được phát ra trong IL. –

Trả lời

22

Theo C# Standard (ECMA-334), một phương pháp được định nghĩa như sau:

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: Phương pháp).

Bây giờ, tiêu chuẩn CLI định nghĩa như sau:

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)

Điều này có nghĩa, rằng trong C#, một phương pháp trở về void không cần lệnh return. Tuy nhiên, khi trình biên dịch C# biên dịch mã C# thành Mã IL, nó yêu cầu kết thúc đường dẫn ở cuối phương thức, nó phát ra một ret để kết thúc phương thức.

17

Thực sự là bắt buộc để mã có thể xác minh được. Nếu không, PEVerify sẽ xuất ra thông báo lỗi sau:

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

8

Từ 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 có tiêu đề 'Đường hầm QSIG qua SIP' –

+0

Rất tiếc, được phát hiện rõ. –

Các vấn đề liên quan