Я получаю «Переменная x недоступна из-за оптимизации» - PullRequest
5 голосов
/ 06 июня 2011

Я получаю «Переменная ForAllUsers, недоступная из-за оптимизации», даже если для конфигурации сборки задано «Отладка», а «Оптимизация» неверна.Итак, я не могу отладить свою программу.

Почему я получаю это?
Какая сборка запускается при нажатии кнопки Run?
Как я могу увидеть


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;


Обновление:
Всего несколько минут с тех пор, как я опубликовал этот вопрос, и за него уже дважды проголосовали и два раза снимались.Кажется, это довольно распространенная проблема.Принял ответ, предоставленный Давидом.

Ответы [ 3 ]

10 голосов
/ 06 июня 2011

Время от времени мы все страдаем от этого. Иногда я добавляю ложный код в тот момент, когда мне нужно отладить переменную, которая ссылается на переменную, но ничего не делает. Например:

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

Или, если это логическое значение, то:

if b then b := not not b;

Что-то в этом духе обычно достаточно, чтобы компилятор выписал код, который поддерживает переменную, чтобы отладчик мог ее проверить. Убедитесь, что вы поместили код прямо внизу процедуры! И убедитесь, что вы не забыли удалить его, прежде чем проверять код.

8 голосов
/ 06 июня 2011

Посмотрим на разницу с оптимизацией и без нее в коде:

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 голосов
/ 07 июня 2011

Код, который вы выложили , не компилируется как есть , поэтому я не могу быть на 100%, что я не убил случай воспроизведения своими личными модификациями, чтобы он запустился ... но я не могу воспроизвести вашу конкретную проблему . Кто-нибудь еще, кто может?

Конечно, отладчик / оценщик жалуется, когда оптимизация включена, но проблема определенно исчезает с выключенной оптимизацией и перестройкой. Вы уверены, что сделали правильное восстановление?

Я не согласен с утверждением Дэвидса о том, что "мы все время от времени страдаем от этого". Помимо известных и предсказуемых граничных случаев (переменные находятся вне области видимости с точкой останова в конце), на самом деле никогда не сталкивается с этой проблемой. Пока я запрещаю коллегам проверять dproj в управлении версиями с включенной оптимизацией, то есть.

...