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

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

Ошибка в try-finally-end? [D5, D6, NT4, Win2k]


spi ©   (2002-05-17 08:19:00) 

Давно меня мучает вопрос: "Почему никто не обращает внимание на неадекватное поведение конструкции try-finally-endв Delphi?"
Дело в том, что блок завершения, обозначенный оператором finally, должен срабатывать при выходе из блока try при помощи оператора Exit, а вместо этого уходим на конец процедуры (функции).

Пример:

a := 1;
hFile := CreateFile(...);
try
if a =1 then
Exit;
a := 2;
finally
CloseHandle(hFile)
end;
end;

В данном примере освобождение дескриптора hFile не произойдет, т.к. оператор Exit передаст управление на конец функции. Оператор return в соответствующей конструкции языка C ведет себя по другому....


spi   (2002-05-18 11:37:00) [1]

Ребята, спасибо, дествительно поведение отладчика D6 вызвало у меня недоумение. Вопрос с повестки дня снимается.


NailS   (2002-05-17 14:57:00) [2]

Посмотрим, что пишет Борланд в хелпе про finally

try statementList1 finally statementList2 end;

If a call to the Exit, Break, or Continue procedure causes control to leave statementList1, statementList2 is automatically executed. Thus the finally clause is always executed, regardless of how the try clause terminates.


Song   (2002-05-17 14:40:00) [3]

Поведение отладчика вовсе ни о чёи не говорит...


Victor_Kozel   (2002-05-17 14:34:00) [4]

Народ, хочу поставить точку, а то у меня впечатление, что
каждый остался при своем мнении.
обработчики try..finally вызываются даже после процедуры Exit.
Я думаю spi был введен в заблуждение поведением отладчика
последних версий делфи - для входа в обработчик finally необходимо нажать F7 а не F8, т.е. зделать trace into.
В четвертой версии проход отладчика осуществлялся в любом случае.


Игорь Шевченко   (2002-05-17 11:47:00) [5]

Victor_Kozel (17.05.02 11:28)

Чуть больше строк для проверки:

unit Controls.pas

// Free the first available device context
procedure FreeDeviceContext;
var
I: Integer;
begin
with CanvasList.LockList do
try
for I := 0 to Count-1 do
with TControlCanvas(Items[I]) do
if TryLock then
try
FreeHandle;
Exit;
finally
Unlock;
end;
finally
CanvasList.UnlockList;
end;
end;


Вряд ли в Borland считают, что Exit не вызовет срабатывание блоков finally :-)

С уважением,


Song   (2002-05-17 11:35:00) [6]

В данном контесте оператор, инструкция - не имеет принципиальной разницы.


Victor_Kozel   (2002-05-17 11:28:00) [7]

1. Пять строк для проверки :-)

try
exit;
finally
showMessage("ok");
end;

2. Ни Abort ни Exit не являются операторами.
Abort просто генерит EAbort эксэпшен. Что касается Exit - читайте help.
The standard procedure Exit can occur within the body of any procedure or function. Exit halts execution of the routine where it occurs and immediately passes program control back to the point from which the routine was called.


Mystic   (2002-05-17 09:36:00) [8]

Нет, дескриптор будет освобожден в любом случае. Перед тем, как перейти на конец функции при выполнении Exit, автоматически выполнятяться все finally-блоки. Тут ты не прав..


Song   (2002-05-17 08:23:00) [9]

Неа, блок завершения, обозначенный оператором finally, должен срабатывать при выходе из блока try при помощи оператора Abort, а никак не Exit. Последний служит для выхода из текущего модуля.


Наверх

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