【问题标题】:Delphi 2006 optimization bugDelphi 2006 优化错误
【发布时间】:2014-05-13 20:11:22
【问题描述】:

如果同时激活溢出检查和优化,Delphi 2006 中存在错误。该错误似乎只出现在将 32 位整数添加到自身,然后以特定顺序将一个字节添加到之前的总和的特定情况下,如下面的程序所示。

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.

注意:溢出检查必须在源文件中编码,而不是通过项目选项。 这导致了另一个错误:通过项目选项进行溢出检测无效。

从 CPU 窗口中可以看出,优化器被 零扩展 movzx 移动(将 8 位值扩展为 32 位值)和溢出检查分心,忘记加载字节b 在一个单独的寄存器上,覆盖以前的内容,最终将 b 添加到自身而不是 2i。以下汇编代码的上半部分属于错误函数,而下半部分属于正常构造。

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 

顺便说一句,这段代码不是一个病态的例子,我是在将 D.Knuth 的宏伟 TeX 程序改编为现代 Pascal 时发现的。在检查启用优化和关闭所有编译器检查对最终 *.exe 大小的影响时,它无法正确解释磁盘保存的哈希表(在关闭优化的情况下生成),我追溯到上面的bug,就是生成表格的部分。

问题很简单,有人可以在较新版本的 Delphi 上检查程序吗?

【问题讨论】:

  • 我在XE4中测试过,结果是一样的:2再1
  • 感谢您的测试,格雷。
  • 我在 XE3 中测试过,结果是相同的 2 和 1。但如果我切换到 64 位,它会打印正确的结果。

标签: delphi


【解决方案1】:

即使在最新版本的 Delphi XE6 中也没有修复该错误。该错误不影响 64 位 Windows 编译器。该错误早在 Delphi 6 就存在,这是我可以运行的最旧版本。

我强烈建议您提交 QC 报告。

【讨论】:

  • QC report 生成,大卫。感谢您的测试。
  • 我投票给那个 QC 并添加了信息,这个错误仍然存​​在于 XE6 中
  • 历史记录:它也出现在 Delphi 2 到 Delphi 5 中。
  • @gammatester 谢谢。我手头没有Delphi 2!听起来这个错误是在 32 位编译器的第一个版本中引入的,并且设法坚持下去!
  • 根据QC的说法,这个bug终于在2014年7月31日消除了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
相关资源
最近更新 更多