Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.06.03;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.004 c
15-1328346033
Smile
2012-02-04 13:00
2012.06.03
Субботняя задачка :)


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


15-1327520756
Dimka Maslov
2012-01-25 23:45
2012.06.03
Что я не правильно делаю?


15-1328025054
Димка На
2012-01-31 19:50
2012.06.03
Что такой ath sin?


15-1328211602
oldman
2012-02-02 23:40
2012.06.03
Классный текст песни!!! (выдержка)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский