由于优化,我得到'变量x无法访问

时间:2011-06-06 19:24:45

标签: delphi delphi-xe delphi-ide

即使构建配置设置为“Debug”且优化为False,我也会因“优化”而无法访问“变量ForAllUsers”。所以,我无法调试我的程序。

为什么我会这样? 按“运行”按钮时会运行哪个构建? 我怎么看?


procedure Test(ForAllUsers: boolean);
VAR
   FName, Path1, Path2: string;
   RootKey: HKEY;
begin
 Result:= FALSE;
 TRY
  if ForAllUsers
  then
    begin
     RootKey:= HKEY_CLASSES_ROOT;
     Path1:= '';
     Path2:= '';
    end
  else
    begin
     RootKey:= HKEY_CURRENT_USER;           <----- Break point here
     Path1:= '\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\';
     Path2:= '\Software\Classes\';    
    end;

... 端;


更新:
我发布这个问题只有几分钟,它已经两次投票并且出演了两次。似乎这是一个非常常见的问题。接受David提供的答案。

3 个答案:

答案 0 :(得分:10)

我们不时都受此影响。我有时会做的是在我需要调试引用变量的变量但不执行任何操作的位置添加一些虚假代码。例如:

if x>0 then x := x*1;

或者如果它是布尔值,那么:

if b then b := not not b;

这些行中的某些内容通常足以让编译器写出使变量保持活动状态的代码,以便调试器可以检查它。确保将代码放在例程的底部!并确保在检查代码之前记得删除它。

答案 1 :(得分:8)

让我们看看代码中是否有优化的区别:

procedure test;
var
  x,y,z: integer;
begin
  x:= 1;   //x is stored in register EAX.
  Inc(x);  
  y:= x;   //this is a no-op because it's just a rename.
//After this point x is no longer used.
//Here you will get `Variable x inaccessible here due to optimization`
  z:= 0;   //z is never used 
  if (y = 1) then Inc(z);  //because Delphi knows this code will never execute
end;

以下是汇总代码 优化:

Project5.dpr.12: x:= 1;   //x is stored in register EAX.
004085E8 B801000000       mov eax,$00000001
Project5.dpr.13: Inc(x);  
004085ED 40               inc eax
Project5.dpr.18: if (y = 1) then Inc(z);
004085EE 48               dec eax  //test to see if eax=1, triggers `jz` if true.
                                   //Delphi put it in to facilitate the `if`, but
                                   //is not smart enough to eliminate it :-)
Project5.dpr.19: end;
004085EF C3               ret 

这是没有优化的代码:

Project5.dpr.11: begin    //note that Delphi doesn't use registers, but the stack 
                          //to keep variables.
004085E8 55               push ebp
004085E9 8BEC             mov ebp,esp      //init the stack frame.
004085EB 83C4F4           add esp,-$0c
Project5.dpr.12: x:= 1;   //x is stored near the top of the stack.
004085EE C745FC01000000   mov [ebp-$04],$00000001
Project5.dpr.13: Inc(x);  
004085F5 FF45FC           inc dword ptr [ebp-$04]
Project5.dpr.14: y:= x;   //y sits on the stack frame.
004085F8 8B45FC           mov eax,[ebp-$04]
004085FB 8945F8           mov [ebp-$08],eax
Project5.dpr.17: z:= 0;    //z is also in the stack frame.
004085FE 33C0             xor eax,eax
00408600 8945F4           mov [ebp-$0c],eax
Project5.dpr.18: if (y = 1) then Inc(z);
00408603 837DF801         cmp dword ptr [ebp-$08],$01
00408607 7503             jnz $0040860c
00408609 FF45F4           inc dword ptr [ebp-$0c]
Project5.dpr.19: end;     //all vars stay in scope.
0040860C 8BE5             mov esp,ebp  //until the stack frame is dismantled.
0040860E 5D               pop ebp  
0040860F C3               ret 

所以你的情况应该永远在优化关闭时发生,但是......

您也可以在源代码中设置优化开启/关闭:

{$Optimization on/off}  or
{$O+/-}

如果该行在您的例程前面,它将覆盖全局设置。

http://docwiki.embarcadero.com/RADStudio/en/Optimization_%28Delphi%29

答案 2 :(得分:2)

您发布的代码不会按原样编译,所以我不能100%我没有通过我的个人修改来杀死复制案例以使其运行... 但我无法重现您的特定问题。还有谁可以吗?

当然,调试器/评估器在优化开启时会抱怨,但问题肯定会随着优化和重建而消失。你确定你做了正确的重建吗?

我有点不同意戴维斯的声明,“我们时不时都会遭受这种痛苦”。除了已知和可预测的边界情况(变量超出了断点的范围)我实际上永远不会遇到这个问题。只要我阻止我的同事通过优化来检查dproj到版本控制,那就是。