Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.06.03;
Скачать: CL | DM;

Вниз

try .. finally внутри try .. except   Найти похожие ветки 

 
Nucer   (2012-01-24 16:22) [0]

Код:
procedure MyProc;
begin
 try
   ...
   Obj := TObj.Create;
   try
     ...
     Value := ...;
     ...
   finally
     Obj.Free;
   end;
   if Value then ...;
   ...
 except
   ...
 end;
end;


Delphi 7 предупреждает об ошибке:
[Warning] Unit1.pas(438): Variable "Value" might not have been initialized

Ошибка среды? Или я что-то делаю не так?


 
MBo ©   (2012-01-24 16:27) [1]

Это не ошибка, а предупреждение, ведь Value действительно не всегда  будет присвоено значение.


 
Nucer   (2012-01-24 16:30) [2]

Но ведь если значение не будет присвоено, то и до проверки значения дело не дойдет?


 
sniknik ©   (2012-01-24 16:35) [3]

глобальная переменная... откуда знать что после этой процедуры другая ее не использует?


 
Nucer   (2012-01-24 16:38) [4]

Прошу прощения за неточность(по примеру кода этого не видно), но переменная локальная.


 
Nucer   (2012-01-24 16:42) [5]

Вот реальный пример (можно скопировать в IDE и увидеть предупреждение):
procedure Test;
var
 Obj: TStringList;
 Value: Integer;
begin
 try
   Obj := TStringList.Create;
   try
     if Random(10) = 0 then raise Exception.Create("Error!");
     Value := Obj.Count;
   finally
     Obj.Free;
   end;
   if Value > 0 then Sleep(1000);
 except
   MessageBox(0, "Error!", "Error!", 0);
 end;
end;


 
Ega23 ©   (2012-01-24 16:46) [6]


> Вот реальный пример (можно скопировать в IDE и увидеть предупреждение):


Буратино дали 3 яблока. 2 яблока он съел. Сколько яблок осталось у Буратино?


 
Nucer   (2012-01-24 16:51) [7]


> Буратино дали 3 яблока. 2 яблока он съел. Сколько яблок
> осталось у Буратино?

Одно, но я не вижу связи. Если бы мне была известна причина появления warning"a, то я бе не создавал тему на форуме. С моей точки зрения в коде отсутствует неопределеннность.


 
Ega23 ©   (2012-01-24 16:53) [8]


> Одно, но я не вижу связи.


Не одно, а неизвестно. Ибо неизвестно, сколько яблок было у Буратино до того, как ему дали 3.
Посему - инициализируй локальные переменные, без неоднозначностей.
Поставь в самом начале Value := 0.


 
Dimka Maslov ©   (2012-01-24 17:00) [9]

Компилятору формально по барабану. Он видит, что инициализация переменной происходит внутри блока (неважно какого блока иф или трю), а использование - вне этого блока. Вот и ругается.


 
Nucer   (2012-01-24 17:03) [10]

Добавление в начало "Value := 0" избавит от сообщения, но по сути как раз это и будет ошибкой ("Value assigned to "Value" never used"). Если я не прав, то в каком месте этот 0 теоритически может быть использован?


 
Nucer   (2012-01-24 17:04) [11]


> Dimka Maslov ©   (24.01.12 17:00) [9]

Т. е., грубо говоря, данное предупреждение является ложным?


 
Ega23 ©   (2012-01-24 17:09) [12]


> Т. е., грубо говоря, данное предупреждение является ложным?

1. Локальные переменные не инициализируются.
2. Компилятор не такой умный, как тебе кажется.
3. Если он видит, что "теоретически неинициализированная переменная" может быть использована - он честно тебя предупреждает.
4. В твоём конкретном случае Value вообще не нужна. Перенеси if внутрь try:
procedure Test;
var
 Obj: TStringList;
begin
 try
   Obj := TStringList.Create;
   try
     if Random(10) = 0 then raise Exception.Create("Error!");
     if Obj.Count > 0 then Sleep(1000);
   finally
     Obj.Free;
   end;
 except
   MessageBox(0, "Error!", "Error!", 0);
 end;
end;


 
Dimka Maslov ©   (2012-01-24 17:20) [13]

За прошедший год это уже вторая ветка на ту же тему. Решение одно - явно инициализируй переменные. Это не будет ошибкой, а строки с value assigned never used в объектный код не попадают. Если уж очень не хочется, сделай себе функцийю
procedure Hole(var V);
asm
 ret
end;

и вызывай её вместо Value := 0, тогда ругаццо не будет.


 
Anatoly Podgoretsky ©   (2012-01-24 17:32) [14]

> Ega23  (24.01.2012 16:46:06)  [6]

А чьи яблоки он съел?


 
_Юрий   (2012-01-25 19:59) [15]


> Nucer   (24.01.12 17:04) [11]


> Т. е., грубо говоря, данное предупреждение является ложным?


Да


 
Anatoly Podgoretsky ©   (2012-01-25 20:51) [16]

Предупреждение правильное, не ложное.


 
RWolf ©   (2012-01-26 01:56) [17]


> [16]

при каком стечении обстоятельств в приведённом коде переменная Value не будет инициализирована к моменту проверки её значения?


 
Он же Самуилыч   (2012-01-26 02:03) [18]

Господа, не стоит требовать от компилятора слишком многого. Слава Богу, он еще не искуственный интеллект, иначе работать с ним было бы совсем  невозможно.

Даже и люди-то далеко не все интеллектом блещут... так чего же вы от программы хотите?


 
Inovet ©   (2012-01-26 02:04) [19]

> [17] RWolf ©   (26.01.12 01:56)

При исключении там, где первое многоточие.


 
Он же Самуилыч   (2012-01-26 02:07) [20]


> Inovet ©   (26.01.12 02:04) [19]

Не, дружище, тут ты неправ. Там весь код взят в try-except, поэтому компилятор, будь он умным, вообще не должен выдавать никаких ворнингов. Но он всего лишь компилятор...


 
Inovet ©   (2012-01-26 02:17) [21]

> [20] Он же Самуилыч   (26.01.12 02:07)
> Не, дружище, тут ты неправ.

Во втором многоточии т.е.. При исключении отработает
Obj.Free;
потом
if Value then ...;
А она не инициализирована. Нет разве?


 
Anatoly Podgoretsky ©   (2012-01-26 08:42) [22]


> при каком стечении обстоятельств в приведённом коде переменная
> Value не будет инициализирована к моменту проверки её значения?
>

При любом исключение до присвоения, а поскольку у тебя два ряда точек, то мест очень много.


 
RWolf ©   (2012-01-26 09:25) [23]


> Inovet ©   (26.01.12 02:17) [21]
> Во втором многоточии т.е.. При исключении отработает Obj.Free;
> потом if Value then ...;А она не инициализирована. Нет разве?

Исключение во втором многоточии приведёт к завершению выполнения процедуры из-за исключения сразу же после Obj.Free, до проверки условия управление не дойдёт.


 
RWolf ©   (2012-01-26 09:26) [24]

т.е. управление провалится сразу в except-секцию.


 
Inovet ©   (2012-01-26 11:29) [25]

> [24] RWolf ©   (26.01.12 09:26)
> т.е. управление провалится сразу в except-секцию.

Да.


 
_Юрий   (2012-01-26 20:17) [26]


> Он же Самуилыч   (26.01.12 02:07) [20]


> Не, дружище, тут ты неправ. Там весь код взят в try-except,
>  поэтому компилятор, будь он умным, вообще не должен выдавать
> никаких ворнингов. Но он всего лишь компилятор...


Нет, дружище, тут ты не прав. Внешний try-except тут вообще ни при чем, его можно было бы исключить из модели как лишнюю сущность.
Потому, что управление не попадет на строчку  "if Value then ...;" в случае возникновения исключения выше независимо от того, есть этот внешний блок, или его нету.
Если же ты считаешь, что внутри try-except вообще не должно быть варнингов потому, что потом идет exept, то тут ты опять не прав.
Обязательно должны быть. Напомню, что у нас в VCL-Forms вообще все обработчики сообщений по умолчанию стоят внутри глобального try-except (отлов исключений на уровне Application). А также все запуски в потоке потомков TThread тоже, то есть практически весь код приложения, кроме инициализации и финализации.

Так что тут компилятор выступил нормально. Ненормально он выступил с этим ложным варнингом.
Кстати, в C# обращение к неинициализированной переменной в силу управляемости кода вообще приводит к ошибке компиляции, а не к варнингу. И там подобных косяков нет - все работает четко. Я уж не знаю, почему у них получилось, а у нас нет.
А тут приходится ставить лишнюю инициализацию, что по сути является ошибкой. Лишние операции процессора - пусть мелочь, но принципиально они лишние. И тем не менее, приходится так делать, потому что это меньшее зло, чем оставлять варнинг, или чем отключать варнинги на участке кода - тогда можно пропустить реальную опасность



Страницы: 1 вся ветка

Текущий архив: 2012.06.03;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.01 c
2-1327584652
Chuck Bass
2012-01-26 17:30
2012.06.03
сортировка строк в TStringList по убыванию


15-1327490966
xayam
2012-01-25 15:29
2012.06.03
Формат для чтения двух книг одновременно


15-1327945903
Dimka Maslov
2012-01-30 21:51
2012.06.03
Мордокнига и законы физики


15-1327609803
Юрий
2012-01-27 00:30
2012.06.03
С днем рождения ! 27 января 2012 пятница


15-1328246954
AV
2012-02-03 09:29
2012.06.03
Не работает Beep. Не всегда. Закономерности не вижу.