Delphi Can';不要进入for循环

Delphi Can';不要进入for循环,delphi,debugging,for-loop,Delphi,Debugging,For Loop,我有一个以前从未见过的奇怪问题。现在我有一个for循环: var a,counter: byte; begin a:=0; for counter := 1 to 10 do//I put a breakpoint at this line begin a:=a*5; a:=a+counter; end; end; 如果我在上面的一行设置断点并尝试进入循环,我就做不到。调试器立即跳过循环并走到最后。最后我得到了正确的结果,但我不能一步一步地跟随循环

我有一个以前从未见过的奇怪问题。现在我有一个for循环:

var
 a,counter: byte;
begin
  a:=0; 
   for counter := 1 to 10 do//I put a breakpoint at this line
   begin
     a:=a*5;
     a:=a+counter;
   end;
end;

如果我在上面的一行设置断点并尝试进入循环,我就做不到。调试器立即跳过循环并走到最后。最后我得到了正确的结果,但我不能一步一步地跟随循环。我的意思是,这只是一个简单的例子,不是真正的任务。我只是想知道在什么情况下会发生这种情况?我清楚地记得跟踪循环的所有步骤。我使用Delphi2010。

请参见关闭优化是否会产生影响-在项目选项->编译->代码生成中。

循环中的两行代码都可以完全优化掉;您在循环外对
a
不做任何操作,因此这两个赋值都是不必要的。优化完成后,编译器将离开

for counter := 1 to 10 do 
  ;
实际上,如果没有断点,循环也会被删除,因为它什么都不做


如果您的代码有问题,并且上面的信息没有帮助(在循环运行后使用变量
a
),那么您需要发布真正的代码。这段编成的代码分析起来非常清晰;实际代码中的问题可能就这么简单,或者分析起来要复杂得多。

在对Ken回答的评论中,Mikayil暗示代码在一个过程中。 从代码来看,这也是一个合理的假设

因此,如果我们设置这样的测试:

Procedure Test;
var
  a,counter: byte;
begin
  a:=0;
  for counter := 1 to 10 do//I put a breakpoint at this line
  begin
    a:=a*5;
    a:=a+counter;
  end;
end;

begin
  Test;
end.
设置优化:结果-正如Mikayil观察到的,不可能进入循环

设置优化:结果-可能进入循环,正如ain建议的那样

现在还要考虑一下,Ken回答中Mikayil的问题: 无法进入循环是否是因为
a
的局部范围

肯的回答是否定的,但事实并非如此:

var
  a : byte; // scope of a is outside of the procedure

Procedure Test;
var
  counter: byte;
begin
  a:=0;
  for counter := 1 to 10 do//I put a breakpoint at this line
  begin
    a:=a*5;
    a:=a+counter;
  end;
end;

begin
  Test;
end.
现在不管优化是开还是关,进入循环都是可能的

所以,艾因的回答是绝对正确的。(在XE2中测试)

更新:

要启用步进循环,有三种可能性:

  • 启动优化
  • 在本地范围外声明
    a
  • 在循环后使用
    a
    插入虚拟操作。比如:
    if(a

  • 这两个步骤都不是不常见的调试过程,我发现这就是问题的症结所在。

    你的意思是“循环什么都不做”,因为循环处理的所有事情都只是变量,范围仅限于过程本身,对吗?不,我的意思是循环什么都不做,因为它什么都不做。读取代码-
    a
    被赋值为
    5
    ,然后立即赋值为
    a
    5
    )+计数器的当前值,然后循环再次运行并重复相同的过程。因此,循环所做的就是分配
    a
    值,立即丢弃分配的每个值。由于循环中没有发生任何有意义的事情,因此没有理由执行循环。@KenWhite,我可以理解,由于循环后没有使用a,因此循环是无用的。但是,如果以后再使用循环中的计算,那么循环中的计算并不是毫无意义的。1,7,38194..etc是循环迭代的结果a值。“如果之后使用它们”-但它们不是;-)@LURD,在发布的代码中,循环外没有使用
    a
    ,因此分配给它的任何值都是100%无意义的,因此无需运行循环。请阅读我写的-我说“在代码张贴”。我还建议Mikayil发布真实代码。实际上,在发布的代码中,
    a
    在其他任何地方都不可用,因为
    var
    begin
    ,并且
    end
    将范围限制为问题中显示的代码。我经常在调试时关闭优化,以便获得编译器已经优化过的变量的值。我认为这在这种情况下没有帮助;无论是否进行优化,发布的代码都毫无意义,甚至没有理由编译它。不可能需要它;这是一个
    NOP
    。OP写道代码只是一个例子,而不是真实的例子。我的回答是指出,通常这类问题是由于优化造成的;关掉它,你就应该能够进入那个毫无意义的循环……你读过我评论中的“在这种情况下”吗?:)我在不止一条评论中(在我的回答中)建议Mikayil发布真实代码,而不是由非功能块组成。我刚才也做了一个观察,;关闭带有发布代码的优化可能仍然不允许单步执行该块。您忘记了优化编译器。你的代码没有任何作用。
    最后我得到了正确的结果,但我不能一步一步地遵循循环。
    你的意思是说你得到了a=3051755?如果这段代码被优化了,就像所有人都同意的那样,我发现这很难相信。@Johan,在发布的代码中没有“结果”,对或错;代码从不执行。这不是真正的代码(在问题的最后一段中是这样说的)。我将Ken的评论解读为“不是因为范围,而是因为没有使用“a”。这不是因为范围,因为如果在循环之后使用“a”,即使“a”是局部的,也不会优化分配。编译器不会优化您的测试用例,因为它不需要搜索“a”是否在其他任何地方使用。我也是这样做的,在这一点上我没有意见分歧。但接下来的问题是
    a
    的局部范围是否使循环无法进入。在对ain回答的评论中,肯认为优化开/关与无法进入循环无关。这是不正确的。@MC9000,Delphi与VS无关。编译器能够优化循环