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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With