![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
try .. finally внутри try .. except
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, то я бе не создавал тему на форуме. С моей точки зрения в коде отсутствует неопределеннность.