Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I get 'Variable x inaccessible here due to optimization'

I get 'Variable ForAllUsers inaccessible here due to optimization' even if the build configuration is set to 'Debug' and the Optimization is False. So, I cannot debug my program.

Why do I get this?
Which build is ran when I press the Run button?
How can I see


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;

... end;


Update:
Only minutes since I posted this question, and it was already voted twice up and starred two times. Seems this is a pretty common issue.

like image 919
Server Overflow Avatar asked Jun 06 '11 19:06

Server Overflow


2 Answers

We all suffer from this from time to time. What I sometimes do is add some spurious code at the point at which I need to debug the variable that references the variable but does nothing. For example:

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

Or if it is a boolean then:

if b then b := not not b;

Something along these lines is usually enough to get the compiler to write out code that keeps the variable alive so that the debugger can inspect it. Make sure you put the code right at the bottom of the routine! And make sure that you remember to remove it before checking the code in.

like image 195
David Heffernan Avatar answered Nov 25 '22 20:11

David Heffernan


Let's see the difference with and without optimization in code:

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;

Here's the assembly code with optimization:

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 

And here's the code without optimization:

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 

So your situation should never occur with optimization off, but...

You can set optimization on/off in the source code too:

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

If that line is in front of your routine it will override the global setting.

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

like image 34
Johan Avatar answered Nov 25 '22 20:11

Johan