2012-06-13 25 views
14

Thứ tự được tính trong đó các tham số được tính trước khi một thủ tục được gọi là định nghĩa trong Delphi?Trong Delphi, các tham số được đánh giá theo thứ tự khi được chuyển vào một phương thức?

IOW, nếu tôi có mã xấu xí này (tìm thấy một cái gì đó như thế này trong một ứng dụng di sản) ...

function A(var err: integer): integer; 
begin 
    err := 42; 
    Result := 17; 
end; 

Test(A(err), err); 

... là thử nghiệm đảm bảo để nhận được các thông số (17, 42) hoặc có thể nó cũng được (17, không xác định)?


Edit:

Mặc dù ví dụ của David trả về kết quả khác nhau với 32-bit và 64-bit trình biên dịch, điều này (may mắn) không ảnh hưởng đến mã di sản của tôi, vì thử nghiệm (A (err), err) chỉ lưu trữ một địa chỉ của 'err' trong thanh ghi và nó không quan trọng cho dù trình biên dịch thực hiện điều này trước khi gọi A (err) hoặc sau.

+2

Bài viết này có thể quan tâm http://blog.barrkel.com/ 2008/04/c-evaluation-order-gotcha.html –

+1

Một bài đăng khác về điều này: http://stackoverflow.com/questions/3054526/delphi-compiler-directive-to-evaluate-arguments-in-reverse –

+0

@David, Tôi đã nhận thức được tính năng C 'này và tôi đã học trên SO rằng Java và C# đánh giá từ trái sang phải nhưng tôi không thể nhớ nơi Delphi có tài liệu này (và như chúng ta đã học, tài liệu sai). – gabr

Trả lời

12

Thứ tự đánh giá tham số trong Delphi không được xác định.

Là một trình diễn thú vị này, chương trình sau đây đã đầu ra khác nhau tùy thuộc vào việc bạn nhắm mục tiêu mã 32 hoặc 64 bit:

program ParameterEvaluationOrder; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

function SideEffect(A: Integer): Integer; 
begin 
    Writeln(A); 
    Result := A; 
end; 

procedure Test(A, B: Integer); 
begin 
end; 

begin 
    Test(SideEffect(1), SideEffect(2)); 
    Readln; 
end. 
+0

Trong Win64, thứ tự đánh giá được xác định bởi quy ước một và chỉ gọi, AFAIK. Trong Win32, có các quy ước gọi khác nhau, và chúng không chỉ định thứ tự đánh giá, chỉ là thứ tự đi qua. –

+4

@RudyVelthuis Theo hiểu biết tốt nhất của tôi, hãy gọi các quy ước chỉ định thứ tự * truyền * nhưng không chỉ định thứ tự * đánh giá *. Vì vậy, tôi tranh luận rằng bình luận. –

+0

IMO, quy ước gọi điện có thể chỉ định bất cứ điều gì họ muốn, chức năng gọi WRT. Nếu thứ tự đánh giá được chỉ định quá, vì lý do gì mà nhà phát triển nền tảng có thể có, bạn nên làm theo các thông số kỹ thuật. Nhưng tôi đồng ý rằng, AFAIK, cho đến bây giờ, không có quy ước gọi điện thoại nào đã làm điều này. –

5

được sửa đổi: có vẻ như trình biên dịch có thể vi phạm các hành vi được mô tả trong sự giúp đỡ:

Từ Calling Conventions chủ đề trợ giúp (tôi nhấn mạnh):

Sổ đăng ký và pascal ước vượt qua các thông số từ trái sang phải; có nghĩa là, thông số bên trái nhiều nhất là được đánh giá và thông qua đầu tiên và tham số ngoài cùng bên phải được đánh giá và vượt qua cuối cùng.

+0

Hóa ra tài liệu bạn liên kết là không chính xác. –

+0

nó làm cho một buồn rằng hành vi của trình biên dịch không tương ứng với nguồn tài liệu chính thức duy nhất – MBo

+0

Tôi đồng ý. Cá nhân tôi cảm thấy nó là tốt cho thứ tự đánh giá là không xác định, nhưng các tài liệu không nên nhà nước khác. –

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