подход к try-catch
От: Аноним  
Дата: 05.10.05 10:44
Оценка:
Народ, подскажите что можно использовать в случае если во многих методах класса стоит банальный список try-catch блоков, причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?
Re: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 12:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?


Для catch-ей макросы рулят Мои мысли здесь
Автор: Коваленко Дмитрий
Дата: 19.02.03
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: подход к try-catch
От: Conr Россия  
Дата: 05.10.05 12:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Народ, подскажите что можно использовать в случае если во многих методах класса стоит банальный список try-catch блоков, причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?

Если код свой, то проще всего все исключения наследовать от какого-нибудь базового класса, например std::exception. А вот если это невозможно (много переделывать и тд), то имхо макрос вполне уместен...
Re: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 14:39
Оценка: 496 (54)
Hello, Аноним !
You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А> Каким образом можно избавиться от повторяющихся catch

А> блоков, желательно без использования макросов?
Используем "фильтр исключений" (вот так):
void TheFunction()
{
    try {
        //твоя функция
    } catch(...) {
        ExceptionFilter();
    }
}

void ExceptionFilter()
{
    try {
        throw;
    } catch(Exception1 const& e) {
        //делаем одно
    } catch(Exception2 const& e) {
        //делаем второе
    } catch(Exception3 const& e) {
        //делаем третье
    } catch(Exception4 const& e) {
        //делаем четвертое
    } catch(Exception5 const& e) {
        //делаем пятое
    } catch(...) {
        //делаем еще что-то
    }
}


ЗЫ. Естественно, фильтров и их вариаций может быть много...
Posted via RSDN NNTP Server 2.0 beta
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 14:42
Оценка: +1 :)
Здравствуйте, 0xDEADBEEF, Вы писали:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):

Убийца!

DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...


-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 15:39
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

DEA>>Используем "фильтр исключений" (вот так):

КД>Убийца!
Да не расстраивайся ты. Вот подожду чуток (пока рейтинг подрастет) и поставлю тебе троечку
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: подход к try-catch
От: Кодт Россия  
Дата: 05.10.05 16:29
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

Офигеть.
Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?
Перекуём баги на фичи!
Re[4]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 16:30
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>>>Используем "фильтр исключений" (вот так):

КД>>Убийца!
DEA>Да не расстраивайся ты. Вот подожду чуток (пока рейтинг подрастет) и поставлю тебе троечку

Спасибо Ехал домой и думал "Боже, прошел уже час от пережитого потрясения, а я все еще живой!"

Нет, правда — в моей башке произошел прорыв. Хотя моя память мне подсказывает, что я такой финт с throw тоже проделывал — но не в таком контексте.

Красиво
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 16:37
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 0xDEADBEEF, Вы писали:


К>Офигеть.

К>Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?
Я этот метод применил как-то случайно... Сработало.
Покурил стандарт и не нашел ничего чтобы противоречило такому подходу.
Протестил — VC 6.0+, ШСД 8.1, GCC 3.2+, aCC (hp-ux) не ругаются...
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: подход к try-catch
От: Centaur Россия  
Дата: 05.10.05 16:40
Оценка: 30 (3)
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 0xDEADBEEF, Вы писали:


К>Офигеть.

К>Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?

15.1/7: The exception thrown is the one most recently caught and not finished. An exception is considered caught when initialization is complete for the formal parameter of the corresponding catch clause, or when terminate() or unexpected() is entered due to a throw. An exception is considered finished when the corresponding catch clause exits or when unexpected() exits after being entered due to a throw.

15.1/8: If no exception is presently being handled, executing a throw-expression with no operand calls terminate() (15.5.1).


Ничего не говорится про то, что throw обязано находиться непосредственно в catch-обработчике Собственно, если бы это требовалось, то пункт 15.1/8 бы был избыточным. Следовательно, перебрасывать исключение из отдельной функции — легально. И даже вызывать такую функцию, когда нет исключения, тоже легально — поведение полностью определено
Re[2]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 16:54
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Hello, Аноним !

DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):
DEA>
DEA>void TheFunction()
DEA>{
DEA>    try {
DEA>        //твоя функция
DEA>    } catch(...) {
DEA>        ExceptionFilter();
DEA>    }
DEA>}

DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}
DEA>


DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...


как правило для каждой функции/метода своя особенная обработка исключении, а это означает что таких фильтров
будет либо очень много, либо их логика будет слишком запутанной. К тому же из ExceptionFilter достаточно проблематично
повторно вызвать функцию/метод кидающую исключение. Мне кажется такой подход пригоден лишь для обобшения процедуры
фиксирования исключений, но ни как для их обработки, и то в тех случаях когда Exception1 не унаследован от некоторого
базового класса...
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 17:12
Оценка: :)
Здравствуйте, aton, Вы писали:

DEA>>ЗЫ. Естественно, фильтров и их вариаций может быть много...


A>как правило для каждой функции/метода своя особенная обработка исключении,

A>а это означает что таких фильтров будет либо очень много, либо их логика будет слишком запутанной.
...Эта штука может реально пригодиться (я ее так испоьзую) для трансляции "чужих" исключений в исключения базирующиеся на "std::exception" и дальнейшего их rethrow-а. Дело в том, что часто приходится использовать "старые" библиотеки, которые еще не слышали о std::exception и поэтому бросаются всякой фигней вместо нормальных исключений.


A>К тому же из ExceptionFilter достаточно проблематично повторно вызвать функцию/метод кидающую исключение.

Повторно??? А зачем? Чтобы еще раз получить исключение?

A>Мне кажется такой подход пригоден лишь для обобшения процедуры фиксирования исключений,

+1
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 17:18
Оценка:
Здравствуйте, aton, Вы писали:

A>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>фиксирования исключений, но ни как для их обработки

Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать

Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 17:28
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, aton, Вы писали:


A>>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>>фиксирования исключений, но ни как для их обработки

КД>Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать


КД>Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку


например ?
Re[4]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 17:36
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Здравствуйте, aton, Вы писали:


DEA>>>ЗЫ. Естественно, фильтров и их вариаций может быть много...


A>>как правило для каждой функции/метода своя особенная обработка исключении,

A>>а это означает что таких фильтров будет либо очень много, либо их логика будет слишком запутанной.
DEA>...Эта штука может реально пригодиться (я ее так испоьзую) для трансляции "чужих" исключений в исключения базирующиеся на "std::exception" и дальнейшего их rethrow-а. Дело в том, что часто приходится использовать "старые" библиотеки, которые еще не слышали о std::exception и поэтому бросаются всякой фигней вместо нормальных исключений.

А нахрена, что бы протолкнуть исключение вниз, на следующий обработчик? обычно все делается не отходя от кассы

A>>К тому же из ExceptionFilter достаточно проблематично повторно вызвать функцию/метод кидающую исключение.

DEA>Повторно??? А зачем? Чтобы еще раз получить исключение?

Хм... нет, что бы исправить ситуацию и повторить действие, например кончилось место на диске, получили ексепшн,
пользователь подчистил диск, нажал retry, повторили вызов и все заработало

A>>Мне кажется такой подход пригоден лишь для обобшения процедуры фиксирования исключений,

DEA>+1
Re[5]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 18:12
Оценка:
Здравствуйте, aton, Вы писали:

A>>>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>>>фиксирования исключений, но ни как для их обработки

КД>>Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать


Я тут чего-то с арифметкой напутал ... или с логикой Один катч из 2х все равно должен остаться. 50K на катч ...

КД>>Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку


A>например ?


Я думал про построение обобщенных фреймворков. Например, у меня есть библиотека для построения COM-модулей. Она ориентирована на перехват, обработку и обратную трансляюцию исключений базирующихся на std::exception.
HRESULT OLE_ProcessErrorException(REFCLSID              ComponentID,
                                  REFIID                InterfaceID,
                                  const std::exception* pExc,
                                  bool                  TranslateAllException)
{
 HRESULT hr=E_FAIL;

 try
 {
  if(g_OLE_ErrorExceptionHandler!=NULL)
  {
   //call user handler of exceptions
   hr=g_OLE_ErrorExceptionHandler(ComponentID,InterfaceID,pExc,TranslateAllException);
  }
  else
  if(pExc==NULL)
  {
   //unknown exception
   hr=E_UNEXPECTED;
  }
  else
  if(const t_base_com_error* const x=dynamic_cast<const t_base_com_error*>(pExc))
  {
   //create std object of automation error
   hr=x->create_error_info(InterfaceID);
  }
  else
  if(dynamic_cast<const bad_alloc*>(pExc)!=NULL)
  {
   hr=E_OUTOFMEMORY;
  }
  else
  {
   const char* const what=pExc->what();

   hr=E_FAIL;

   if(what!=NULL && (*what)!=0)
    ole_lib::CreateErrorInfo(InterfaceID,what,hr);
  }//else
 }
 catch(...)
 {
  hr=E_FAIL;
 }

 return hr;
}//OLE_ProcessErrorException


Все работает, но меня постоянно долбит мысль о еще одном базовом классе исключений — Exception из VCL, который (в модулях с GUI) тоже может прорваться до этого обработчика. К сожалению только в виде pExc=NULL.

Вот тут-то стратегия нашего убийцы и поможет ...

Правда мысль о том, что фильтр исключений может быть вызван не из catch(){ }, чего-то меня настораживает. Это раз.

Хотя, по-моему, в плюсах есть средство определения — "Мы сейчас обрабатываем исключение или нет?"

Второе: ведь можно писать так
catch(const exception& e)
{
 throw;
}


Ладно, я тут начал уже погружаться в собсвенные мысли...
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[6]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 06:24
Оценка: +1
КД>
КД> catch(...)
КД> {
КД>  hr=E_FAIL;
КД> }
КД>}//OLE_ProcessErrorException
КД>


Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[7]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 06:48
Оценка: +1
Здравствуйте, Tom, Вы писали:

КД>> catch(...)
КД>> {
КД>>  hr=E_FAIL;
КД>> }
КД>>}//OLE_ProcessErrorException


Tom>Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"


А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?

У нас с вами идентичное представление о назначении OLE_ProcessErrorException? Эта центральная функция обработки исключений, сгенерированных внутрях реализаций COM-объектов. И эта обработка тоже может сгенерировать исключение

Или вы предлагаете мне его выпускать наружу? Сомневаюсь, что клиенту COM-объекта это понравится
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[8]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 06:56
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Tom, Вы писали:


КД>
КД>>> catch(...)
КД>>> {
КД>>>  hr=E_FAIL;
КД>>> }
КД>>>}//OLE_ProcessErrorException
КД>


Tom>>Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"


КД>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?


КД>У нас с вами идентичное представление о назначении OLE_ProcessErrorException? Эта центральная функция обработки исключений, сгенерированных внутрях реализаций COM-объектов. И эта обработка тоже может сгенерировать исключение


КД>Или вы предлагаете мне его выпускать наружу? Сомневаюсь, что клиенту COM-объекта это понравится

Что угодно но ге гасить его таким образом, нормальное правило работы с исключениями — перехватывай то, что выкидываешь
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[9]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 07:22
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Что угодно, но ге гасить его таким образом,

По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler.

>нормальное правило работы с исключениями — перехватывай то, что выкидываешь

И что, это правило распространяется и на обработку исключений, которые произошли во время обработки исключения? Для всех типов приложений?

Еще раз повторю, это функция для обработки исключений. Может вызвать другую функцию, а может выполнить обработку по-умолчанию. И уже звиняте — рекурсивные исключение наружу она не выпустит. Потому что "ружа" — инородная среда, которая про исключения может вообще ничего не знать. Поэтому OLE_ProcessErrorException и давит повторные исключения у себя внутрях на корню.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: подход к try-catch
От: Erop Россия  
Дата: 06.10.05 07:50
Оценка:
Здравствуйте, aton, Вы писали:

A>Хм... нет, что бы исправить ситуацию и повторить действие, например кончилось место на диске, получили ексепшн,

A>пользователь подчистил диск, нажал retry, повторили вызов и все заработало


Казалось бы, тогда мы знаем какое исключение ждать и можем не пользоваться в этом месте фильтром, а пользоваться просто catch
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: подход к try-catch
От: Кодт Россия  
Дата: 06.10.05 08:00
Оценка: -1
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?


Заворачиваться в простыню и ползти на кладбище. До тех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову (terminate или abort — надо посмотреть).
Это в случае, если оба исключения возникли в одном потоке и в одном CRT.

В остальных случаях (например, через границу апартаментов, или между С++ной и С-ной функциями, и т.д.) — возможны разные прикольные сочетания, вплоть до возвращения из функции всякого мусора и даже расстрела памяти.
Перекуём баги на фичи!
Re[10]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 08:10
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Tom, Вы писали:


Tom>>Что угодно, но ге гасить его таким образом,

КД>По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler.
Во первых делать обработку так, что бы исключений в обработчике исключений по возможности не возникало, если всё таки они скажем могут возникнуть — то перехватывать именно те, которые могут возникнуть. Вот в твоём примере чего ты "боишься"? Для чего ты пишешь "catch(...)" ?
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[11]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 08:28
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>>>Что угодно, но ге гасить его таким образом,

КД>>По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler.
Tom>Во первых делать обработку так, что бы исключений в обработчике исключений по возможности не возникало, если всё таки они скажем могут возникнуть — то перехватывать именно те, которые могут возникнуть. Вот в твоём примере чего ты "боишься"? Для чего ты пишешь "catch(...)" ?

Для отказоустойчивости. Которой много не бывает.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: подход к try-catch
От: ssm Россия  
Дата: 06.10.05 08:31
Оценка: :)
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Используем "фильтр исключений" (вот так):


Re[12]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 08:32
Оценка: +1
КД>Для отказоустойчивости. Которой много не бывает.
catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[9]: подход к try-catch
От: _Winnie Россия C++.freerun
Дата: 06.10.05 08:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?


К>ех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову

???


int main()
{
    try
    {
        throw 0;
    }
    catch(...)
    {
        try
        {
            throw 0;
        }
        catch(...)
        {
            printf("hello!\n");
        }
    }
}
Правильно работающая программа — просто частный случай Undefined Behavior
Re[13]: подход к try-catch
От: _Winnie Россия C++.freerun
Дата: 06.10.05 08:40
Оценка: +1
Здравствуйте, Tom, Вы писали:

КД>>Для отказоустойчивости. Которой много не бывает.

Tom>catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте

А причем тут AV? Мы вроде как про С++ исключения говорим? Если вылетело SEH исключение, то тут уже игра по другим правилам. Лично я просто делаю делаю попытку save, записываю crash-dump и умираю.

А как ты предлагаешь выкидывать исключения из DLL, которая может использоватьсся даже в другом языке, ничего не знающем про исключения? Тут можно только E_FAIL верунть.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[10]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 08:48
Оценка:
Здравствуйте, _Winnie, Вы писали:

КД>>>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?


К>>ех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову

_W>???

[/ccode]
_W>catch(...)
_W>{
_W> printf("hello!\n");
_W>}
[/ccode]

Тогда уж лучше сразу предложить пользователю абмнормалиться по паре стопариков
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[14]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 08:54
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Здравствуйте, Tom, Вы писали:


КД>>>Для отказоустойчивости. Которой много не бывает.

Tom>>catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте

_W>А причем тут AV? Мы вроде как про С++ исключения говорим? Если вылетело SEH исключение, то тут уже игра по другим правилам. Лично я просто делаю делаю попытку save, записываю crash-dump и умираю.


Уговорил Напакостил в памяти и вылетело не AV а что то типа std::range_error, от этого не легче
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[10]: подход к try-catch
От: Кодт Россия  
Дата: 06.10.05 09:30
Оценка:
Хм. Да, пожалуй, наврал. Интересно, почему такой сдвиг в башке?..
А, сообразил!

Облом происходит, если второе исключение кинуто при размотке стека, т.е. из деструктора.
Перекуём баги на фичи!
Все новое украдено до нас! :)))
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 25.11.05 13:15
Оценка: 71 (4) :))
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Используем "фильтр исключений" (вот так):

DEA>
DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}
DEA>


Перечитывая в очередной раз "Язык программирования C++" 3-е издание нашел этот трюк у Страуструпа!
Причем он там его чуть по другому показывает ($14.6.3.1, $14.6.3.2).

Была, значиться функция
void g() throw(Yerr);

и захотели ее использовать там, где кроме Yerr еще и другие ошибки выскакивают. Что же делать, чтобы std::unexpected() не вызывался? А вот чего:
class STC{ // store and reset class
    unexpected_handler old;
public:
    STC(unexpected_handler f) { old = set_unexpected(f) ; }
    ~STC() { set_unexpected(old) ; }
};

это вроде RAII для установки unexpected_handler. Затем делается новое исключение, производное от Yerr:
class Yunexpected : public Yerr {};

void throwY() throw(Yunexpected) { throw Yunexpected(); }

и предоставляется обертка вокруг g():
void networked_g() throw(Yerr)
{
    STC xx( &throwY ); // Теперь unexpected() генерирует Yunexpected.
    g();
}


Только вот проблема, не известно, что за исключение было порождено. Тогда приведенный выше код модифицируется:
class Yunexpected : public Yerr {
public :
    Network_exception * pe;
    Yunexpected(Network_exception * p) : pe( p ? p->clone() : 0 ) {}
    ~Yunexpected() { delete pe; }
}

void throwY() throw(Yunexpected)
{
    try {
        throw; // Сгенерировать заново, чтобы немедлено перехватить!
    }
    catch( Network_exception & p ) {
        throw Yunexpected(&p); // Сгенерировать отображенное исключение.
    }
    catch( ... ) {
        throw Yunexpected(0);
    }
}



Знакомый до боли принцип в последнем варианте throwY(), не правда ли

А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Все новое украдено до нас! :)))
От: Pavel Chikulaev Россия  
Дата: 25.11.05 13:30
Оценка: :)
Здравствуйте, eao197, Вы писали:

[snipped]
Супер!
+1

E>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно

Сегодня же начну Кстати там и expression templates есть...
Re[2]: Все новое украдено до нас! :)))
От: srggal Украина  
Дата: 25.11.05 14:26
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

E>>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно

PC>Сегодня же начну Кстати там и expression templates есть...

Там много чего, есть, но eao197, как всегда передергивает

Большинство нарицаний было в сторону перевода книги
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Все новое украдено до нас! :)))
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 25.11.05 17:21
Оценка:
Здравствуйте, srggal, Вы писали:

E>>>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно

PC>>Сегодня же начну Кстати там и expression templates есть...

S>Там много чего, есть, но eao197, как всегда передергивает


Да куда уж мне передергивать
Re[2]: Язык программирования C++ (специальное издание)
Автор: LaptevVV
Дата: 11.11.03

Re[3]: Язык программирования C++ (специальное издание)
Автор: Lorenzo_LAMAS
Дата: 11.11.03
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: подход к try-catch
От: remark Россия http://www.1024cores.net/
Дата: 25.11.05 17:32
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Hello, Аноним !

DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):


Неужели про это знали только мы с тобой вдвоём

Пара идей, которые, у меня созрели:


DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...



Практика показывает, что чем меньше, тем лучше.
Если это, например, COM-компонент, то я делаю один фильтр исключений на все методы COM-компонента. Это как нельзя лучше структурирует всё политику обработки исключений в приложении.
Если гуёвое приложение, то я использую 2 — один при выполнении гуёвых команд по действию пользователя, второй для действий, выполняемых в рабочих потоках.


Пару интересных идей по этой теме есть здесь. Хотя, конечно, если пишешь на С++, то самому это всё реализовывать засадно. Хотя в простом варианте реализовать можно.

Например, так:

void exceptionHandler()
{
    ExceptionManager::getHandler().run();
}



Можно применять, например, при работе приложения в нескольких режимах — когда можно показывать мессаджбоксы, и когда нельзя. Или при изменении каких-либо других подсистем приложения, например, провайдера БД.


В крупных проектах, где не обойтись без логирования и мониторинга приложения, я стандартно применяю следующий приём:


void _exceptionHandler(const std::string& sFunctionName)
{
    LOG << "Exception: " << sFunctionName;
    // Реальная обработка исключения
}


#define exceptionHandler() _exceptionHandler(__FUNCTION__)



При жестоком желании не дублировать код (какое у меня обычно бывает ) можно структурно обрабатывать иерархии исключений:


Допустим, есть такая иерархия исключений:

struct A1 {};
struct B1 : A1 {};
struct C1 : A1 {};
struct A2 {};
struct B2 : A2 {};
struct C2 : B2 {};



Её можно обрабатывать следующим обработчиком:


void exceptionHandler()
{
    try
    {
        throw;
    }
    catch (const A1&)
    {
        try
        {
            throw;
        }
        catch (const B1&)
        {
            handlingForB1();
        }
        catch (const C1&)
        {
            handlingForC1();
        }
        handlingForA1();
    }
    catch (const A2&)
    {
        try
        {
            throw;
        }
        catch (const B2&)
        {
            try
            {
                throw;
            }
            catch (const C2&)
            {
                handlingForC2();
            }
            handlingForB2();
        }
        handlingForA2();
    }
    handlingForAllErrors();
};



... Хотя, конечно, это для маньяков



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: подход к try-catch
От: Dobre  
Дата: 08.12.05 14:54
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Hello, Аноним !

DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):
DEA>
DEA>void TheFunction()
DEA>{
DEA>    try {
DEA>        //твоя функция
DEA>    } catch(...) {
DEA>        ExceptionFilter();
DEA>    }
DEA>}

DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}
DEA>


DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...



Приветствую.

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

void TheFunction()
{
    try 
    {
        // предположим у нас тут зовется что-то вроде
        ....
        throw Exception1();
    }
    catch(...) 
    {
        ExceptionFilter();
    }                             // ВОТ ТУТ ВЫЗОВЕТСЯ ДЕСТРУКТОР ВТОРОЙ РАЗ

}

void ExceptionFilter()
{
    try 
    {
        throw;
    } 
    catch(Exception1 const& e) 
    {
        //делаем одно
    }                             // ВОТ ТУТ ВЫЗОВЕТСЯ ДЕСТРУКТОР ПЕРВЫЙ РАЗ
    catch(Exception2 const& e) 
    {
        //делаем второе
    } 
    catch(Exception3 const& e) 
    {
        //делаем третье
    } 
    catch(Exception4 const& e) 
    {
        //делаем четвертое
    } 
    catch(Exception5 const& e) 
    {
        //делаем пятое
    } 
    catch(...) 
    {
        //делаем еще что-то
    }
}



А вот теперь представим, что я пытаюсь отловить exception который определен в какой то сторонней библиотеке. И определен так, что как только мы ему зовем деструктор второй раз, так он тотчаз стреляет мой программе прямо в висок (что если у него в деструкторе стоит: delete pSomePtr

Как жить ? Как быть ? Или может я что то не так сделал ?
Re[3]: подход к try-catch
От: Dobre  
Дата: 08.12.05 16:01
Оценка:
Лююююди, человеки!!!
Спасайте !
Re[3]: подход к try-catch
От: Кодт Россия  
Дата: 08.12.05 22:38
Оценка:
Здравствуйте, Dobre, Вы писали:

<>

Это баг компилятора VC6, VC7. VC7.1 полёт нормальный.
http://www.rsdn.ru/Forum/?mid=412976
Автор: LMars
Дата: 17.10.03
Перекуём баги на фичи!
Re[2]: подход к try-catch
От: AndrewJD США  
Дата: 17.05.06 13:25
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>
DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}

DEA>Используем "фильтр исключений" (вот так):
DEA>void TheFunction()
DEA>{
DEA>    try {
DEA>        //твоя функция
DEA>    } catch(...) {
DEA>        ExceptionFilter();
            throw; // << Заново выбросить
DEA>    }
DEA>}
DEA>


Небольшой вопросик.
Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[3]: подход к try-catch
От: Conr Россия  
Дата: 17.05.06 14:10
Оценка:
Здравствуйте, AndrewJD, Вы писали:

AJD>Небольшой вопросик.

AJD>Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?
Сколько душе угодно
Re[4]: подход к try-catch
От: AndrewJD США  
Дата: 17.05.06 14:35
Оценка:
Здравствуйте, Conr, Вы писали:

AJD>>Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?

C>Сколько душе угодно

Верю . Но хотелось бы цитату из стандарта.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[5]: подход к try-catch
От: Conr Россия  
Дата: 17.05.06 14:50
Оценка: 4 (1)
Здравствуйте, AndrewJD, Вы писали:

AJD>Здравствуйте, Conr, Вы писали:


AJD>>>Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?

C>>Сколько душе угодно

AJD>Верю . Но хотелось бы цитату из стандарта.


15.1
6) A throw-expression with no operand rethrows the exception being handled. The exception is reactivated
with the existing temporary; no new temporary exception object is created. The exception is no longer considered
to be caught; therefore, the value of uncaught_exception() will again be true.

Re[5]: подход к try-catch
От: MuTPu4  
Дата: 17.05.06 15:05
Оценка:
Здравствуйте, AndrewJD, Вы писали:

AJD>Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?

Стандарт не налагает каких-либо ограничений на этот счет. Исключение может быть переброшено тогда и только тогда, когда оно обрабатывается, если это условие выполнено, то выброс исключения корректен не зависимо от "вложенности".

AJD>Верю . Но хотелось бы цитату из стандарта.

(15.1/6):

A throw-expression with no operand rethrows the exception being handled.
...
The exception is no longer considered to be caught;
...


(15.1/7):

...
An exception is considered caught when initialization is complete for the formal parameter of the corresponding catch clause
...
An exception is considered finished when the corresponding catch clause exits
...


(15.1/8):

If no exception is presently being handled, executing a throw-expression with no operand calls terminate()


(15.3/8)

An exception is considered handled upon entry to a handler.

Re[2]: маленький недостаток
От: Аноним  
Дата: 18.05.06 13:17
Оценка:
При использовании такого фильтра, как я понимаю есть небольшой шанс получить:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Press any key to continue


Например, если написать вот так:

#include <iostream>

//---------------------------------------
void ExceptionFilter () {
    try {
        throw;
    }
    catch (...) {
        std::cout << "in ExceptionFilter ..." << std::endl;
    }
}

//---------------------------------------
bool c () {
    ExceptionFilter (); // формально никто нам не запрещает написать (случайно при copy/paste) так где-то глубоко в коде.
    return true;
}

//---------------------------------------
bool b () {
    return c();
}

//---------------------------------------
bool a () {
    return b();
}

//---------------------------------------
int main () {
    try {

        a (); 
        
    }
    catch (...) {
        ExceptionFilter();
        std::cout << "in main ... " << std::endl;
    }
    return 0;
}
Re[2]: подход к try-catch
От: Аноним  
Дата: 19.05.06 12:05
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Hello, Аноним !

DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):
DEA>
DEA>void TheFunction()
DEA>{
DEA>    try {
DEA>        //твоя функция
DEA>    } catch(...) {
DEA>        ExceptionFilter();
DEA>    }
DEA>}

DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}
DEA>


DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...


Интересно что этот вопрос и это решение с фильтром возникает с устойчевой периодичностью в месяцев ~ 6. И каждай раз восторги. Интрересно можно это время (6 месяцем) считать периодом практически полного обновления читателей форума.
Re[3]: маленький недостаток
От: MuTPu4  
Дата: 19.05.06 22:35
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>При использовании такого фильтра, как я понимаю есть небольшой шанс получить:


А>This application has requested the Runtime to terminate it in an unusual way.

А>Please contact the application's support team for more information.
А>Press any key to continue


А>Например, если написать вот так:


Я бы упростил пример:

void ExceptionFilter () {
    try {
        throw;
    }
    catch (...) {
        std::cout << "in ExceptionFilter ..." << std::endl;
    }
}

int main( void )
{
  ExceptionFilter(); // формально никто нам не запрещает написать (случайно при copy/paste) так где-то глубоко в коде.
}


Re[2]: подход к try-catch
От: Maxim S. Shatskih Россия  
Дата: 27.07.07 14:22
Оценка:
DEA>Используем "фильтр исключений" (вот так):

О! Кода уже не меньше, чем с обычной проверкой кода ошибки, вдобавок он разрозненный.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[3]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 30.07.07 06:50
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

DEA>>Используем "фильтр исключений" (вот так):


MSS>О! Кода уже не меньше, чем с обычной проверкой кода ошибки, вдобавок он разрозненный.


Максим, Вы меня разачаровываете

Приведенный подход — отличное решение для интеграции независимых разработок, компилируемых вместе, и для централизованной обработки исключений (та самая разрозненность, которая вам не нравится, есть ни что иное как отделение основного кода от кода обработки ошибок).

А коды ошибок, особенно в чистом виде, — это даже не вчерашний день.

Сейчас даже использование исключений для транспортировки "тупого текста с описанием" — это не кошерно. Возникают грабли при локализации и попытках добавить сведения о слоях, через которые исключение будет выскакивать наружу.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.