8

ビルド構成が「デバッグ」に設定されていて、最適化が 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;

... 終わり;


更新:
この質問を投稿してからわずか数分で、すでに 2 回の投票と 2 回のスターが付けられました。これはかなり一般的な問題のようです。

4

3 に答える 3

11

私たちは皆、時々これに苦しんでいます。私が時々行うことは、変数を参照するが何もしない変数をデバッグする必要がある時点で、いくつかの偽のコードを追加することです。例えば:

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

または、ブール値の場合:

if b then b := not not b;

これらの行に沿った何かは、デバッガーがそれを検査できるように、変数を有効に保つコードをコンパイラーに書き出させるのに通常は十分です。コードは必ずルーチンの一番下に配置してください。また、コードをチェックインする前に、忘れずに削除してください。

于 2011-06-06T19:36:17.990 に答える
9

コードで最適化を行った場合と行わない場合の違いを見てみましょう。

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

于 2011-06-06T19:46:08.627 に答える
2

あなたが投稿したコードはそのままではコンパイルされないため、100% になることはできません。実行するために個人的な変更を加えて再現ケースを強制終了しませんでした...しかし、特定の問題を再現することはできません。他にできる人いますか?

確かに、最適化がオンの場合、デバッガー/エバリュエーターは不平を言いますが、最適化をオフにして再構築すると、問題は確実に解消されます。適切な再構築を行ったと確信していますか?

「私たちは皆、時々これに苦しんでいる」というDavidsの声明にはちょっと同意しません. 既知の予測可能な境界ケース (変数が範囲外でブレークポイントが最後にある) を除けば、実際にこの問題に遭遇することはありません。同僚が最適化をオンにして dproj をバージョン管理にチェックインするのを防ぐ限り、つまり。

于 2011-06-06T20:12:07.567 に答える