Delphi对For变量的优化(不可思议)

来源:互联网 发布:sqlserver时间戳转换 编辑:程序博客网 时间:2024/04/28 11:17

有下面一段代码:

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
const Item:array[0..18-1]of LongWord =

(1 , 3 ,5 ,7 ,9 , 11, 13 ,15, 17, 19 , 21 , 23, 25 , 27, 29, 31 , 33 ,35

);
begin
for i := 0 to 17 do
begin
//g_CMem.GetRam(270);
//ShowMessage(IntToStr(i));
//ShowMessage('a');
//Memo1.Lines.add(IntToStr(i));//如果打印此变量i的值,单步跟踪显示的i值正确,
Memo1.Lines.add(IntToStr(Item[i])+'a');//而为什么此处间接显示以i表示的Item数组变量的值,跟踪时发现i被编译器优化为Downto的形式,从18到1的形式,但打印出的结果却正确,造成错觉?
end;
end;



如果程序中没有直接使用For变量的值,Delphi编译器会把For语句优化为Downto的形式(如果程序中是使用For...to...),调试程序时需要特别注意,当跟踪For变量的值时,编译器显示的值会和程序中使用的语句表达式的值不一样,但如果使用显示的变量用Watch监视是正确的,比如,当程序第一次运行for i:=0 to 17时,我们可以知道i的值为0,但跟踪时编译器显示i的值为18,Item[i]=4222796,为什么会这样呢? 因为Item数组只有18个元素,下标只到17,所以Item[18]当然是一个随机的值了, 估计可能是因为编译器把For语句优化为For i:=18 downto 的形式,我看到过一篇介绍在Unix下,Downto形式的For语句会比to形式的For语句要快,因为经编译器编译为汇编程序时,Downto形式的For语句比To形式的For语句少一条汇编代码,这样就使得程序执行效率提高了,只是在跟踪时可能显示的是优化的值吧!Delphi但如果我们把Item[0]添加到Watch中,显示Item[0]=1是正确的。