2014-05-13 12 views
24

Có lỗi trong Delphi 2006 nếu kích hoạt kiểm tra tràn và tối ưu hóa. Lỗi này dường như chỉ xuất hiện trong tình huống cụ thể trong đó một số nguyên 32 bit được thêm vào chính nó, và sau đó một byte được thêm vào tổng số trước đó, theo thứ tự cụ thể này, như được thấy trên chương trình bên dưới.Lỗi tối ưu hóa Delphi 2006

program OptimizationBug; 
{$OPTIMIZATION ON} 
{$APPTYPE CONSOLE} 

{$OVERFLOWCHECKS ON} 
function f: integer; 
var i: integer; 
    b: byte; 
begin 
    i:=0; 
    b:=1; 
    Result:=i+i+b; 
end; 

{$OVERFLOWCHECKS OFF} 
function g: integer; 
var i: integer; 
    b: byte; 
begin 
    i:=0; 
    b:=1; 
    Result:=i+i+b; 
end; 

begin 
    writeLn(f); //wrong, prints "2" in D2006 
    writeLn(g); //good, prints "1" 
    readLn; 
end. 

Lưu ý: Kiểm tra tràn phải được mã hóa trong tệp nguồn chứ không phải qua tùy chọn dự án. Điều này dẫn chúng ta đến một lỗi khác: Phát hiện tràn qua các tùy chọn dự án không có hiệu lực.

Như đã thấy trên cửa sổ CPU, tôi ưu hoa bị phân tâm bởi một động thái với zero mở rộng movzx (mở rộng một giá trị 8-bit đến một giá trị 32 bit) và bởi việc kiểm tra tràn, quên để tải byte b trên một thanh ghi riêng biệt, ghi đè các nội dung trước đó, với hiệu ứng ròng của việc thêm b vào chính nó thay vì 2i. Nửa trên của mã lắp ráp dưới đây thuộc về chức năng bị lỗi trong khi nửa dưới của cấu trúc lành mạnh.

OptimizationBug.dpr.20: i:=0; 
00403EAC 33C0    xor eax,eax 
OptimizationBug.dpr.21: b:=1; 
00403EAE B201    mov dl,$01 
OptimizationBug.dpr.22: Result:=i+i+b; 
00403EB0 03C0    add eax,eax 
00403EB2 7105    jno $00403eb9 
00403EB4 E82BF5FFFF  call @IntOver 
00403EB9 0FB6C2   movzx eax,dl //BUG: should have x-moved DL to EDX register! 
00403EBC 03C0    add eax,eax  //  (and added EDX to EAX) 
00403EBE 7105    jno $00403ec5 
00403EC0 E81FF5FFFF  call @IntOver 
OptimizationBug.dpr.23: end; 
00403EC5 C3    ret 
00403EC6 8BC0    mov eax,eax 
OptimizationBug.dpr.30: i:=0; 
00403EC8 33C0    xor eax,eax 
OptimizationBug.dpr.31: b:=1; 
00403ECA B201    mov dl,$01 
OptimizationBug.dpr.32: Result:=i+i+b; 
00403ECC 03C0    add eax,eax 
00403ECE 0FB6D2   movzx edx,dl //OK! 
00403ED1 03C2    add eax,edx  //ok 
OptimizationBug.dpr.33: end; 
00403ED3 C3    ret 

Nhân tiện, mã này không phải là một ví dụ bệnh lý, tôi tìm thấy nó trong khi điều chỉnh chương trình TeX tuyệt vời của D.Knuth thành Pascal hiện đại. Khi kiểm tra hiệu quả của việc bật tối ưu hóa và tắt tất cả các kiểm tra trình biên dịch trên kích thước * .exe cuối cùng, nó không thể diễn giải các bảng băm được lưu lại một cách chính xác (được tạo ra với tối ưu hóa bị tắt), mà tôi truy tìm lại ở trên lỗi, là phần tạo ra các bảng.

Câu hỏi rất đơn giản, ai đó có thể kiểm tra chương trình trên phiên bản mới hơn của Delphi?

+2

Tôi đã thử nghiệm ở XE4 và kết quả giống nhau: 2 và sau đó 1 – Graymatter

+0

Cảm ơn bạn đã kiểm tra, Gray. –

+0

tôi đã thử nghiệm trong XE3 và kết quả là như nhau 2 và sau đó 1. nhưng nếu tôi chuyển sang 64-bit, nó sẽ in kết quả chính xác. –

Trả lời

9

Lỗi chưa được sửa ngay cả trong phiên bản mới nhất của Delphi, XE6. Lỗi này không ảnh hưởng đến trình biên dịch Windows 64 bit. Lỗi này hiện diện xa như Delphi 6, phiên bản cũ nhất mà tôi có thể chạy.

Tôi thực sự khuyên bạn nên gửi báo cáo QC.

+5

[Báo cáo QC] (http://qc.embarcadero.com/wc/qcmain.aspx?d=124769) được tạo, David. Cảm ơn bạn đã thử nghiệm. –

+4

Tôi đã bỏ phiếu cho QC đó và thêm thông tin, rằng lỗi này vẫn còn hiện diện trong XE6 –

+7

Lưu ý lịch sử: Nó cũng có mặt trong Delphi 2 đến Delphi 5. – gammatester