Except Or Finally?

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Except Or Finally?

Сообщение alex208210 » 20.06.2011 15:44:49

ну и темы у вас)))
Пользую 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;

в этом случает пользователь увидит повод поматериться, но съэкономит кучу нервов, не пугуясь ОШИБКИ!!!!

И плодить кучу блоков друг в друге не вижу удобным и наглядным для понимания кодом
alex208210
постоялец
 
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Re: Except Or Finally?

Сообщение Max Rusov » 20.06.2011 15:47:20

Обычно - как раз наоборот: много вложенных 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;
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: Except Or Finally?

Сообщение alex208210 » 20.06.2011 15:58:18

все же удобнее и понятнее будет

Код: Выделить всё
try
if КакоеТоУсловие then
   begin
    выполняем_действие;
    ОсвобождаемРесурсы;
    exit;
   end;
except
   ОсвобождаемРесурсы;
   exit;
end;
Последний раз редактировалось alex208210 20.06.2011 15:59:45, всего редактировалось 1 раз.
alex208210
постоялец
 
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Re: Except Or Finally?

Сообщение Max Rusov » 20.06.2011 15:59:23

OMG :(
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: Except Or Finally?

Сообщение ronin » 20.06.2011 16:05:32

Принципиальна разница как раз в том, что finally _не_ подавляет exception, исполнение алгоритма прерывается, он проходит по всем вложенным Finally частям пока не попадет в завершающий Except. Без finally на одних except'ах этого очень тяжело добиться


я посмотрел на тестовом примере, при исключительной ситуации finally подавил вывод сообщения об ошибке, аналогично exception'у, так что я сам в раздумье в чём разница о_О
ronin
постоялец
 
Сообщения: 174
Зарегистрирован: 27.01.2010 00:14:46

Re: Except Or Finally?

Сообщение Max Rusov » 20.06.2011 16:14:33

Пример в студию.
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: Except Or Finally?

Сообщение alex208210 » 20.06.2011 16:18:46

ronin обманывать не хорошо)
Вложения
teste.rar
(123.34 КБ) Скачиваний: 401
alex208210
постоялец
 
Сообщения: 207
Зарегистрирован: 12.05.2010 13:16:51

Re: Except Or Finally?

Сообщение evd » 20.06.2011 16:42:30

Не всегда имеет смысл обрабатывать исключения в каждой процедуре/методе.
Например:
Код: Выделить всё
//Одна из множества процедур, вызываемая из RunBigOperation
procedure SomethingWrong;
begin
  //Выделяем память
  try
   ........
   raise Exception.Create('Что-то пошло не так');
  finally
   //Освождаем память
  end;
end;

procedure RunBigOperation();
begin
   try
      SomethingWrong();
   except
      //Большой код обработки исключения
   end;
end;


В данном примере в процедуре выполниться блок finally, а затем пойдет в except процедуры RunBigOperation, где ошибка и обработается
К тому же не всегда имеет смысл в процедуре ловить все исключения
Аватара пользователя
evd
новенький
 
Сообщения: 21
Зарегистрирован: 13.09.2009 09:42:28
Откуда: Вологда

Re: Except Or Finally?

Сообщение Max Rusov » 20.06.2011 16:51:23

Вообще, в 99% случаев не требуется писать except, всегда есть корневой except в базовых библиотеках. Свой except надо писать только если по каким-то причинам не устраивает стандартная обработка исключения. Это очень редко.
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: Except Or Finally?

Сообщение daesher » 20.06.2011 21:42:22

Max Rusov писал(а):Вообще, в 99% случаев не требуется писать except, всегда есть корневой except в базовых библиотеках. Свой except надо писать только если по каким-то причинам не устраивает стандартная обработка исключения. Это очень редко.

Ну почему редко? Практически всегда, когда мы знаем, что на этом участке в достаточно штатной ситуации может быть ошибка (идеально, конечно, поймать её условиями, но не всегда оно того стоит). Пользователь будет совсем не рад отвечать на вопрос о том, снять ли приложение или продолжить выполнение.
А иногда бывает, что некоторые действия можно было бы выполнить, но это не суть как важно, если что-то там сорвётся; сообщать пользователю о таких мелочах совсем не стоит.

Добавлено спустя 6 минут 10 секунд:
Чтобы не быть голословным: допустим, мы строим график функции, функция задаётся в виде переменной процедурного типа или даже события (возможно, она программируется совершенно другим пользователем, которому, разумеется, лень проводить проверку на ОДЗ, и тем более не удобно передавать как-то результат этой проверки); в какой-то области функция не существует. Логично, что на каждую такую точку при каждой перерисовке графика программа ругаться не должна; было бы идеально, чтобы точка просто не строилась! И она не будет строиться, если заключить её (вызов функции и построение точки) в блок try...except...end. Единственное, между except и end, по большому счёту, и ставить нечего.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: Except Or Finally?

Сообщение Odyssey » 20.06.2011 22:54:07

daesher писал(а):Ну почему редко? Практически всегда, когда мы знаем, что на этом участке в достаточно штатной ситуации может быть ошибка

Вот по-хорошему, такие случаи должно быть очень редко :) Потому что исключения, по определению, предназначены для исключительных, т.е. нештатных ситуаций.

daesher писал(а):А иногда бывает, что некоторые действия можно было бы выполнить, но это не суть как важно, если что-то там сорвётся; сообщать пользователю о таких мелочах совсем не стоит.

Тут согласен, хотя нужно очень чётко фильтровать "мелочи" от не мелочей, т.е.
Код: Выделить всё
try
  // SomeAction
except
  on E: ESmallException do begin end;
end;

Если использовать просто "except end;" - можно вместе с мелочами пропустить серьёзную проблему, например чреватую потерей данных.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Except Or Finally?

Сообщение Max Rusov » 20.06.2011 23:48:57

Посмотрел, ради интереса, в своих исходниках. Слово "finally" Встресается ~7600 раз, слово "except" ~2700. В исходниках VCL приблизительно то же соотношение 3:1. Видимо - закон природы :)
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: Except Or Finally?

Сообщение Widowmaker » 21.06.2011 00:22:34

Видимо, наипростейший случай:
Код: Выделить всё
//...
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+}, программа вываливалась с сообщением об ошибке открытия файла, если его на диске не было, чего и следовало ожидать. Ваял много чего ещё, но и в других случаях, в том числе и в С++, нужды в этих конструкциях тоже ни разу не возникло. Наверное, они были придуманы специально в декоративных целях -- для украшения кода и придания ему большего наукообразия. :lol:
Аватара пользователя
Widowmaker
новенький
 
Сообщения: 37
Зарегистрирован: 27.04.2011 18:32:04

Re: Except Or Finally?

Сообщение Sergei I. Gorelkin » 21.06.2011 02:32:31

Класс Exception и (почти) вся обработка исключений находятся в модуле sysutils. В простейших программах без использования sysutils исключения работать не будут.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Except Or Finally?

Сообщение Widowmaker » 21.06.2011 03:36:21

Так в том-то и дело, что SysUtils используется :
Код: Выделить всё
unit GSW;
//
{$mode objfpc}{$H+}
//
interface
//
uses
  Classes, SysUtils, {FileUtil}, MedFilter;
type
  TGSW = class ( TObject )
  //
//...
end; // type

, однако получается, что директивы {$I-} ... {$I+} нужны безотносительно к способу обработки ошибки открытия несуществующего файла.
Аватара пользователя
Widowmaker
новенький
 
Сообщения: 37
Зарегистрирован: 27.04.2011 18:32:04

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23

Рейтинг@Mail.ru