今天我遇到了一个非常奇怪的错误。
我有下一个代码:
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)编译器。
答案 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变量包含正确的值。
也许,我的经验对某人有用。感谢所有帮助我的人,请对不起我的无意识错误。