2011-06-06 49 views
5

即使构建配置设置为'调试'并且优化为假,我也会得到'变量ForAllUsers由于优化而无法访问'。所以,我无法调试我的程序。我得到'由于优化'变量x无法访问'

为什么我得到这个?
当我按下“运行”按钮时,哪个版本运行?
我怎么能看到


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提供的答案。

+0

显示您遇到的问题的代码,我会帮助。 – 2011-06-06 19:28:28

+0

这是正常的(有点烦人)。您只需在其他时间检查变量(而不是在'end'语句处)。 – 2011-06-06 19:29:32

+0

嗨安德烈亚斯。我从D7知道这个问题。这很烦人,但实际上并没有那么多。但事实并非如此。我正处于我的程序中。 – Ampere 2011-06-06 19:33:51

回答

10

我们都不时遭受这种痛苦。我有时候做的是在我需要调试引用变量但什么都不做的变量的地方添加一些伪代码。例如:

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

或者如果它是一个布尔值,则:

if b then b := not not b; 

东西沿着这些线路通常是足以让编译器写出来,保持该变量活代码,以便调试器可以检查它。确保你把代码放在例程的底部!并确保你还记得在检查代码前将其删除

+1

+1如果b然后b:=不是b;':)当然你是对的。无论如何,阅读价值已经足够了。你不需要分配它。 – 2011-06-06 19:42:49

+0

嗨大卫。这在Delphi 7下发生过吗?直到现在我还没有看到它(除非执行点确实在例程的末尾) – Ampere 2011-06-06 19:43:20

+0

@daemon_x我永远无法确定你需要做多少事来说服编译器按我的意愿行事。我倾向于在安全方面犯错! – 2011-06-06 19:45:25

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

+0

嗨,约翰。这就是我所做的!我已经在'项目选项'中将优化设置为关闭。在PAS文件中,我没有看到将它再次设置为OFF的要点。特别是当我想从Debug切换到Release版本时,这将是一个真正的动物园。可能我会忘记删除{$ O-}指令。但我很确定这只是一个Delphi XE错误。总而言之,他们只发布了Delphi XE的Update 1。对。我们将不得不等待更新2,3,4,5 ....甚至可能是6. – Ampere 2011-06-06 19:54:42

+0

我只是说你可能在某个地方留下了{$ O +}。在你的var超出范围并右键点击菜单之前,你可以在点**之前打破它,选择'debug-> view CPU'。复制粘贴问题中的相关部分。 – Johan 2011-06-06 19:57:14

+0

“我只是说你可能在某处留下了{$ O +}” - 这就是我的观点:我不使用这个编译器指令只是因为我可能会忘记它。这是我的规则。我会做一个搜索,但它没用,因为我从来没有违反这个规则。 – Ampere 2011-06-06 20:04:01

2

您发布不编译原样,所以我不能100%我没有杀我的个人modificications再现的情况下,使其运行的代码... 但我无法重现您的特定问题。任何人都可以?

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

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

+1

你可能是对的,也许是我做错了什么。我从来没有真正努力去弄清楚究竟是什么导致我使用像我在答案中描述的技巧。我通常更感兴趣的是解决眼前的问题,而不是深入研究。 – 2011-06-06 21:06:00

+0

@David这可能是一种比过分关注像我这样的小生产力问题更加健康的态度......然后,我们的后辈们在他们第一次遇到他们时倾向于这些东西,而我不愿意回答他们“忽略并拨弄,直到它的作品“。除非紧缩,否则。 :) – 2011-06-07 07:01:55