For循环变量违反循环绑定

时间:2015-01-12 17:30:56

标签: delphi for-loop

今天我遇到了一个非常奇怪的错误。

我有下一个代码:

var i: integer;
...
for i := 0 to FileNames.Count - 1 do
begin
  ShowMessage(IntToStr(i) + ' from ' + IntToStr(FileNames.Count - 1));
  FileName := FileNames[i];
  ...
end; 
ShowMessage('all');

FileNames列表有一个元素。所以,我认为然后循环将执行一次,我看到

0 from 0
all

这是我做过几千次的事情:)。 但是在这种情况下,我会看到第二次循环迭代,当时代码优化已经开启

0 from 0
1 from 0
all

没有代码优化循环迭代正确。 目前我甚至不知道移动这个问题的方向(并且上部环路保持不变,是)。

所以任何建议都会非常有用。感谢。

我使用Delphi 2005(Upd2)编译器。

2 个答案:

答案 0 :(得分:3)

考虑到LU RD提到的质量控制报告,以及我自己对D2005的经验,这里有一些解决方法。我记得自己使用while循环解决方案。

1.将for循环写为while循环

var
  i: integer;
begin
  i := 0;
  while i < FileNames.Count do
  begin
    ...
    inc(i);
  end;
end;

2.单独从任何其他处理中获取for循环控制变量,并使用一个单独的变量,在循环中递增,用于字符串操作和FileNames索引。

var
  ctrl, indx: integer;
begin
  indx := 0;
  for ctrl := 0 to FileNames.Count-1 do
  begin
    // use indx for string manipulation and FileNames indx
    inc(indx);
  end;
end;

3.你在Without code optimization loop iterates right.说明了一个解决方法 假设你有优化,在程序/函数之前将其关闭({$ O-}),之后再次关闭({$ O +})。注意! Optimization指令只能用于至少整个过程/函数。

答案 1 :(得分:0)

好吧,在我看来,我解决了这个问题并且可以解释它。 不幸的是,我无法进行测试来重现这个bug,而且我无法显示NDA下的真实代码。所以我必须再次使用简化的例子。

问题在于我的代码中使用的dll。考虑下一个数据结构:

type
  TData = packed record
    Count: integer;
  end;
  TPData = ^TData;

和函数,在dll中定义:

Calc: function(Data: TPData): integer; stdcall;

在我的代码中,我尝试继续从列表中获取的数据记录(TList):

var
  i: integer;
  Data: TData;
begin
  for i := 0 to List.Count - 1 do
  begin
    Data := TPData(List[i])^;
    Calc(@Data);
  end;

并且在优化开启的情况下,我看到循环中的第二次迭代从0到0。 如果重写代码为

var
  i: integer;
  Data, Data2: TData;
begin
  for i := 0 to List.Count - 1 do
  begin
    Data := TPData(List[i])^;
    Data2 := TPData(List[i])^;
    Calc(@Data2);
  end;

一切按预期工作。

Dll本身是由另一位程序员开发的,所以我请他照顾它。

对我来说意外的是 - 本地程序的堆栈可能以非常不寻常的方式被破坏,没有访问冲突或其他类似错误。 BTW,Data和Data2变量包含正确的值。

也许,我的经验对某人有用。感谢所有帮助我的人,请对不起我的无意识错误。