Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

try .. finally внутри try .. except


Страницы:   1 2

Nucer ©   (2012-01-24 16:22:00) 

Код:
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

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


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


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


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


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

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


Inovet   (2012-01-26 11:29:00) [2]

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

Да.


RWolf   (2012-01-26 09:26:00) [3]

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


RWolf   (2012-01-26 09:25:00) [4]


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

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


Anatoly Podgoretsky   (2012-01-26 08:42:00) [5]


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

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


Inovet   (2012-01-26 02:17:00) [6]

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

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


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


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

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


Inovet   (2012-01-26 02:04:00) [8]

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

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


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

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

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


RWolf   (2012-01-26 01:56:00) [10]


> [16]

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


Anatoly Podgoretsky   (2012-01-25 20:51:00) [11]

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


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


> Nucer   (24.01.12 17:04) [11]


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


Да


Anatoly Podgoretsky   (2012-01-24 17:32:00) [13]

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

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


Dimka Maslov   (2012-01-24 17:20:00) [14]

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

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


Ega23   (2012-01-24 17:09:00) [15]


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

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;


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


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

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


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

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


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

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


Ega23   (2012-01-24 16:53:00) [19]


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


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


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


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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо