Страница 2 из 3
Re: Except Or Finally?
Добавлено: 20.06.2011 15:44:49
alex208210
ну и темы у вас)))
Пользую except в любом случае..
В примерах всегда показывают например так:
idhttp1:=idhttp1.create();
try
str:=idhttp1.get('ya.ru');
finally
idhttp1.free;
end;
смысл в том что не зависимо от ситуации (наличие/отсутвие Интернета).. компонент уничтожается.. но если Интернета нет, то пользователь увидит не очень хорошее сообщение с красным крестиком ААААА ОШИБКА!!!!
idhttp1:=idhttp1.create();
try
str:=idhttp1.get('ya.ru');
idhttp1.free;
except
idhttp1.free;
showmessage('Упс походу инета нет');
end;
в этом случает пользователь увидит повод поматериться, но съэкономит кучу нервов, не пугуясь ОШИБКИ!!!!
И плодить кучу блоков друг в друге не вижу удобным и наглядным для понимания кодом
Re: Except Or Finally?
Добавлено: 20.06.2011 15:53:17
Max Rusov
Обычно - как раз наоборот: много вложенных try-finally, а снаружи - try-except.
Код: Выделить всё
try
АллоцируемРесурс1;
try
//...
АллоцируемРесурс2;
try
//...
finally
ОсвобождаемРесурс2;
end;
//...
finally
ОсвобождаемРесурс1;
end;
except
ОбрабатываемОшибку;
end;
Конечно, обычно, вложенные try-finally находятся в вызываемых процедурах, я "распрямил" для наглядности.
Добавлено спустя 5 минут 57 секунд:Еще неочевидной особенностью try-finally является то, что управление попадет в finally блок, даже если исполнение процедуры прекращается по exit (или цикла по break). Правда - насчет goto - не уверен

.
Код: Выделить всё
procedure Some;
begin
АлолцируемРесурсы;
try
//...
if КакоеТоУсловие then
Exit; // Все равно попадем в finally часть, хоть это и не исключение.
//...
finally
ОсвобождаемРесурсы;
end;
end;
Re: Except Or Finally?
Добавлено: 20.06.2011 15:58:18
alex208210
все же удобнее и понятнее будет
Код: Выделить всё
try
if КакоеТоУсловие then
begin
выполняем_действие;
ОсвобождаемРесурсы;
exit;
end;
except
ОсвобождаемРесурсы;
exit;
end;
Re: Except Or Finally?
Добавлено: 20.06.2011 15:59:23
Max Rusov
OMG

Re: Except Or Finally?
Добавлено: 20.06.2011 16:05:32
ronin
Принципиальна разница как раз в том, что finally _не_ подавляет exception, исполнение алгоритма прерывается, он проходит по всем вложенным Finally частям пока не попадет в завершающий Except. Без finally на одних except'ах этого очень тяжело добиться
я посмотрел на тестовом примере, при исключительной ситуации finally подавил вывод сообщения об ошибке, аналогично exception'у, так что я сам в раздумье в чём разница о_О
Re: Except Or Finally?
Добавлено: 20.06.2011 16:14:33
Max Rusov
Пример в студию.
Re: Except Or Finally?
Добавлено: 20.06.2011 16:18:46
alex208210
ronin обманывать не хорошо)
Re: Except Or Finally?
Добавлено: 20.06.2011 16:42:30
evd
Не всегда имеет смысл обрабатывать исключения в каждой процедуре/методе.
Например:
Код: Выделить всё
//Одна из множества процедур, вызываемая из RunBigOperation
procedure SomethingWrong;
begin
//Выделяем память
try
........
raise Exception.Create('Что-то пошло не так');
finally
//Освождаем память
end;
end;
procedure RunBigOperation();
begin
try
SomethingWrong();
except
//Большой код обработки исключения
end;
end;
В данном примере в процедуре выполниться блок finally, а затем пойдет в except процедуры RunBigOperation, где ошибка и обработается
К тому же не всегда имеет смысл в процедуре ловить все исключения
Re: Except Or Finally?
Добавлено: 20.06.2011 16:51:23
Max Rusov
Вообще, в 99% случаев не требуется писать except, всегда есть корневой except в базовых библиотеках. Свой except надо писать только если по каким-то причинам не устраивает стандартная обработка исключения. Это очень редко.
Re: Except Or Finally?
Добавлено: 20.06.2011 21:48:32
daesher
Max Rusov писал(а):Вообще, в 99% случаев не требуется писать except, всегда есть корневой except в базовых библиотеках. Свой except надо писать только если по каким-то причинам не устраивает стандартная обработка исключения. Это очень редко.
Ну почему редко? Практически всегда, когда мы знаем, что на этом участке в достаточно штатной ситуации может быть ошибка (идеально, конечно, поймать её условиями, но не всегда оно того стоит). Пользователь будет совсем не рад отвечать на вопрос о том, снять ли приложение или продолжить выполнение.
А иногда бывает, что некоторые действия можно было бы выполнить, но это не суть как важно, если что-то там сорвётся; сообщать пользователю о таких мелочах совсем не стоит.
Добавлено спустя 6 минут 10 секунд:Чтобы не быть голословным: допустим, мы строим график функции, функция задаётся в виде переменной процедурного типа или даже события (возможно, она программируется совершенно другим пользователем, которому, разумеется, лень проводить проверку на ОДЗ, и тем более не удобно передавать как-то результат этой проверки); в какой-то области функция не существует. Логично, что на каждую такую точку при каждой перерисовке графика программа ругаться не должна; было бы идеально, чтобы точка просто не строилась! И она не будет строиться, если заключить её (вызов функции и построение точки) в блок try...except...end. Единственное, между except и end, по большому счёту, и ставить нечего.
Re: Except Or Finally?
Добавлено: 20.06.2011 22:54:07
Odyssey
daesher писал(а):Ну почему редко? Практически всегда, когда мы знаем, что на этом участке в достаточно штатной ситуации может быть ошибка
Вот по-хорошему, такие случаи должно быть очень редко

Потому что исключения, по определению, предназначены для исключительных, т.е. нештатных ситуаций.
daesher писал(а):А иногда бывает, что некоторые действия можно было бы выполнить, но это не суть как важно, если что-то там сорвётся; сообщать пользователю о таких мелочах совсем не стоит.
Тут согласен, хотя нужно очень чётко фильтровать "мелочи" от не мелочей, т.е.
Код: Выделить всё
try
// SomeAction
except
on E: ESmallException do begin end;
end;
Если использовать просто "except end;" - можно вместе с мелочами пропустить серьёзную проблему, например чреватую потерей данных.
Re: Except Or Finally?
Добавлено: 20.06.2011 23:48:57
Max Rusov
Посмотрел, ради интереса, в своих исходниках. Слово "finally" Встресается ~7600 раз, слово "except" ~2700. В исходниках VCL приблизительно то же соотношение 3:1. Видимо - закон природы

Re: Except Or Finally?
Добавлено: 21.06.2011 00:22:34
Widowmaker
Видимо, наипростейший случай:
Код: Выделить всё
//...
fdata : TextFile; // текстовый файл для чтения / записи информации
begin
err_code := 0;
//
case ( opmode_ ) of
1 : // чтение данных
begin
AssignFile ( fdata, filename_ );
//
{$I-} // передаём контроль ошибок ввода/вывода программе
Reset ( fdata );
{$I+} // восстанавливаем автоматический контроль ошибок ввода/вывода
//
if ( IOResult <> 0 ) then
begin
err_code := -101;
exit ( err_code ); // выход
end; // if ( IOResult <> 0 )
// если файл данных существует и открылся
//...
end;
//...
end;
Стало интересно, можно ли обойтись без {$I-} ... {$I+}. Пробовал и try ... except, и try ... finally, однако пока не поставил {$I-} ... {$I+}, программа вываливалась с сообщением об ошибке открытия файла, если его на диске не было, чего и следовало ожидать. Ваял много чего ещё, но и в других случаях, в том числе и в С++, нужды в этих конструкциях тоже ни разу не возникло. Наверное, они были придуманы специально в декоративных целях -- для украшения кода и придания ему большего наукообразия.

Re: Except Or Finally?
Добавлено: 21.06.2011 02:32:31
Sergei I. Gorelkin
Класс Exception и (почти) вся обработка исключений находятся в модуле sysutils. В простейших программах без использования sysutils исключения работать не будут.
Re: Except Or Finally?
Добавлено: 21.06.2011 03:36:21
Widowmaker
Так в том-то и дело, что SysUtils используется :
Код: Выделить всё
unit GSW;
//
{$mode objfpc}{$H+}
//
interface
//
uses
Classes, SysUtils, {FileUtil}, MedFilter;
type
TGSW = class ( TObject )
//
//...
end; // type
, однако получается, что директивы {$I-} ... {$I+} нужны безотносительно к способу обработки ошибки открытия несуществующего файла.