Здравствуйте, aton, Вы писали:
A>Хм... нет, что бы исправить ситуацию и повторить действие, например кончилось место на диске, получили ексепшн, A>пользователь подчистил диск, нажал retry, повторили вызов и все заработало
Казалось бы, тогда мы знаем какое исключение ждать и можем не пользоваться в этом месте фильтром, а пользоваться просто catch
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?
Заворачиваться в простыню и ползти на кладбище. До тех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову (terminate или abort — надо посмотреть).
Это в случае, если оба исключения возникли в одном потоке и в одном CRT.
В остальных случаях (например, через границу апартаментов, или между С++ной и С-ной функциями, и т.д.) — возможны разные прикольные сочетания, вплоть до возвращения из функции всякого мусора и даже расстрела памяти.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Здравствуйте, Tom, Вы писали:
Tom>>Что угодно, но ге гасить его таким образом, КД>По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler.
Во первых делать обработку так, что бы исключений в обработчике исключений по возможности не возникало, если всё таки они скажем могут возникнуть — то перехватывать именно те, которые могут возникнуть. Вот в твоём примере чего ты "боишься"? Для чего ты пишешь "catch(...)" ?
Здравствуйте, Tom, Вы писали:
Tom>>>Что угодно, но ге гасить его таким образом, КД>>По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler. Tom>Во первых делать обработку так, что бы исключений в обработчике исключений по возможности не возникало, если всё таки они скажем могут возникнуть — то перехватывать именно те, которые могут возникнуть. Вот в твоём примере чего ты "боишься"? Для чего ты пишешь "catch(...)" ?
Для отказоустойчивости. Которой много не бывает.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Для отказоустойчивости. Которой много не бывает.
catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?
К>ех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову
???
Здравствуйте, Tom, Вы писали:
КД>>Для отказоустойчивости. Которой много не бывает. Tom>catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте
А причем тут AV? Мы вроде как про С++ исключения говорим? Если вылетело SEH исключение, то тут уже игра по другим правилам. Лично я просто делаю делаю попытку save, записываю crash-dump и умираю.
А как ты предлагаешь выкидывать исключения из DLL, которая может использоватьсся даже в другом языке, ничего не знающем про исключения? Тут можно только E_FAIL верунть.
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, _Winnie, Вы писали:
КД>>>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?
К>>ех пор, пока одно исключение не завершено, бросок другого исключения (пусть даже мы его ловим) приведёт к аварийному останову _W>???
Здравствуйте, _Winnie, Вы писали:
_W>Здравствуйте, Tom, Вы писали:
КД>>>Для отказоустойчивости. Которой много не бывает. Tom>>catch(...) не добавляет отказоустойчивости, а наабарот. Поясню, допустим ты залез в обработчике эксепшина куда то далеко в память и напакостил там, а потом вылеьел по AV, AV сглотнётся и о том, что произошло ты никогда не узнаешь, а потом будешь долго чесать репу почему в совершенно другом куске кода программа спотыкается на ровном месте
_W>А причем тут AV? Мы вроде как про С++ исключения говорим? Если вылетело SEH исключение, то тут уже игра по другим правилам. Лично я просто делаю делаю попытку save, записываю crash-dump и умираю.
Уговорил Напакостил в памяти и вылетело не AV а что то типа std::range_error, от этого не легче
Перечитывая в очередной раз "Язык программирования 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(); }
Знакомый до боли принцип в последнем варианте throwY(), не правда ли
А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
[snipped]
Супер!
+1
E>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно
Сегодня же начну Кстати там и expression templates есть...
Здравствуйте, Pavel Chikulaev, Вы писали:
E>>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно PC>Сегодня же начну Кстати там и expression templates есть...
Там много чего, есть, но eao197, как всегда передергивает
Большинство нарицаний было в сторону перевода книги
Здравствуйте, srggal, Вы писали:
E>>>А еще недавно тема всплывала, где книгу Страуструпа ругали, мол попса, все поверхносно и написано не понятно. А классиков, оказывается, перечитывать полезно PC>>Сегодня же начну Кстати там и expression templates есть...
S>Там много чего, есть, но eao197, как всегда передергивает
Здравствуйте, 0xDEADBEEF, Вы писали:
DEA>Hello, Аноним ! DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:
А>> Каким образом можно избавиться от повторяющихся catch А>> блоков, желательно без использования макросов? DEA>Используем "фильтр исключений" (вот так):
Неужели про это знали только мы с тобой вдвоём
Пара идей, которые, у меня созрели:
DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...
Практика показывает, что чем меньше, тем лучше.
Если это, например, COM-компонент, то я делаю один фильтр исключений на все методы COM-компонента. Это как нельзя лучше структурирует всё политику обработки исключений в приложении.
Если гуёвое приложение, то я использую 2 — один при выполнении гуёвых команд по действию пользователя, второй для действий, выполняемых в рабочих потоках.
Пару интересных идей по этой теме есть здесь. Хотя, конечно, если пишешь на С++, то самому это всё реализовывать засадно. Хотя в простом варианте реализовать можно.
Можно применять, например, при работе приложения в нескольких режимах — когда можно показывать мессаджбоксы, и когда нельзя. Или при изменении каких-либо других подсистем приложения, например, провайдера БД.
В крупных проектах, где не обойтись без логирования и мониторинга приложения, я стандартно применяю следующий приём:
Здравствуйте, 0xDEADBEEF, Вы писали:
DEA>Hello, Аноним ! DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:
А>> Каким образом можно избавиться от повторяющихся catch А>> блоков, желательно без использования макросов? 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
Как жить ? Как быть ? Или может я что то не так сделал ?
Небольшой вопросик.
Сколько раз, согласно стандарту, мы можем перевыбрасывать одно и то же исключение? Т.е. первый раз мы перевыбросили исключение в фильтре. Насколько законно его еще раз выбросить?
"For every complex problem, there is a solution that is simple, neat,
and wrong."