Приветствую форум.
Подскажите ка, как лучше сделать. Хотелось что-то типа:
try
{
// делаем что-то
...
// если плохо, кидаем exceptionif(bad)
{
throw Tralialia();
}
}
finally
{
// какие-то действия
finally_proc1();
finally_proc2();
finally_proc3();
// если был exception, то он полетит дальше
}
Понятно, что на c++ finally как бы нету, поэтому самым простым и банальным было бы решить это так:
try
{
// делаем что-то
...
// если плохо, кидаем exceptionif(bad)
{
throw Tralialia();
}
}
catch(...)
{
// какие-то действия
finally_proc1();
finally_proc2();
finally_proc3();
// если был exception, то он полетит дальшеthrow;
}
finally_proc1();
finally_proc2();
finally_proc3();
но это выглядит как-то криво.
И ещё, подскажите тогда, в чём принципиальное различие будет, если использовать __try и __finally? Например, в нашем же случае:
__try
{
// делаем что-то
...
// если плохо, кидаем exceptionif(bad)
{
throw Tralialia();
}
}
__finally
{
// какие-то действия
finally_proc1();
finally_proc2();
finally_proc3();
// если был exception, то он полетит дальше
}
Здравствуйте, Димчанский, Вы писали:
Д>Приветствую форум.
И вас приветствую.
Д>И ещё, подскажите тогда, в чём принципиальное различие будет, если использовать __try и __finally? Например, в нашем же случае: Д>
Д>__try
Д>{
Д> // делаем что-то
Д> ...
Д> // если плохо, кидаем exception
Д> if(bad)
Д> {
Д> throw Tralialia();
Д> }
Д>}
Д>__finally
Д>{
Д> // какие-то действия
Д> finally_proc1();
Д> finally_proc2();
Д> finally_proc3();
Д> // если был exception, то он полетит дальше
Д>}
Д>
Это, как говорят, SEH. А попросту — обработка исключений средствами Windows. Расширение, предоставляеое системами под Windows (Visual — точно, а Борланд — не помню, но вроде тоже). На других платформах работать не будет. Но если перенос некритичен — вполне можно использовать. Подробности можно прочитать у Рихтера.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
Д>>И ещё, подскажите тогда, в чём принципиальное различие будет, если использовать __try и __finally? Например, в нашем же случае: LVV>Это, как говорят, SEH. А попросту — обработка исключений средствами Windows. Расширение, предоставляеое системами под Windows (Visual — точно, а Борланд — не помню, но вроде тоже). На других платформах работать не будет. Но если перенос некритичен — вполне можно использовать. Подробности можно прочитать у Рихтера.
Что-то тут на форуме говорили, что там деструкторы только не вызываются в случае __try и _finally...
Может быть кто-то толково мог бы это объяснить. В чём именно там недостаток?
Здравствуйте, Димчанский, Вы писали:
Д>Здравствуйте, Denis, Вы писали:
Д>Спасибо. Гуляя по ссылкам, натолкнулся на такое решение (RAII — Resource Acquisition Is Initialisation): Д>
Д>The following two fragments of code are equivalent:
Здравствуйте, Димчанский, Вы писали:
Д>Здравствуйте, LaptevVV, Вы писали:
Д>>>И ещё, подскажите тогда, в чём принципиальное различие будет, если использовать __try и __finally? Например, в нашем же случае: LVV>>Это, как говорят, SEH. А попросту — обработка исключений средствами Windows. Расширение, предоставляеое системами под Windows (Visual — точно, а Борланд — не помню, но вроде тоже). На других платформах работать не будет. Но если перенос некритичен — вполне можно использовать. Подробности можно прочитать у Рихтера.
Д>Что-то тут на форуме говорили, что там деструкторы только не вызываются в случае __try и _finally... Д>Может быть кто-то толково мог бы это объяснить. В чём именно там недостаток?
В С++ при возникновении исключения нормально вызываются деструкторы объектов. А в SEH-нет.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
[]
> Давно хотел спросить: > А почему бы не использовать uncaught_exception() в качестве do_rollback_ ?
Во первых, uncaught_exception() не реализован на MS VC++ (независимо от ситуации возвращает одно и тоже значение). Во-вторых, тебе может понадобиться отменить действие вручную.
Здравствуйте, MaximE, Вы писали:
ME>Андрей Галюзин wrote:
ME>[]
>> Давно хотел спросить: >> А почему бы не использовать uncaught_exception() в качестве do_rollback_ ?
ME>Во первых, uncaught_exception() не реализован на MS VC++ (независимо от ситуации возвращает одно и тоже значение). Во-вторых, тебе может понадобиться отменить действие вручную.
ME>-- ME>Maxim Egorushkin ME>MetaCommunications Engineering ME>http://www.meta-comm.com/engineering/
Реализован, только он называется __uncaught_exception() и расположен в заголовке eh.h.
Здравствуйте, MaximE, Вы писали:
ME>Во первых, uncaught_exception() не реализован на MS VC++ (независимо от ситуации возвращает одно и тоже значение). Во-вторых, тебе может понадобиться отменить действие вручную.
Это Вы в MSDN'е прочитали? Врут Вам, батенька, врут! Что VC70, что VC71 — все прекрасно исполняют.
class A
{
public:
A() {}
~A() { if( std::uncaught_exception() ) ::MessageBox( 0, "", "", MB_OK ); }
};
try
{
A a;
throw 1;
}
catch(...)
{
}
Здравствуйте, PM, Вы писали:
PM>Здраствуйте, Андрей Галюзин. Вы писали:
АГ>> Давно хотел спросить: АГ>> А почему бы не использовать uncaught_exception() в качестве АГ>> do_rollback_ ?
PM>Может быть, потому что Александреску согласен с Саттером по поводу [url= PM>http://www.gotw.ca/gotw/047.htm PM>]Item#47 "Uncaught Exceptions"[/url] ?
Да, для try-catch внутри деструкторов uncaught_exception не катит. Однако, таких ситуаций (объектов, требующих commit-or-rollback) внутри деструкторов нужно избегать (имхо).
P> Может быть, потому что Александреску согласен с Саттером по поводу [url= P> http://www.gotw.ca/gotw/047.htm P> ]Item#47 "Uncaught Exceptions"[/url] ?
Там обсуждается немного другой аспект применения.
На мой взляд, применение unchaught_exception в гуардах вполне кошерно.
Каждый раз писать dismiss несколько утомительно, да и запросто забыть можно.
Здраствуйте, Андрей Галюзин. Вы писали:
P>> Может быть, потому что Александреску согласен с Саттером по поводу P>> Item#47 "Uncaught<br />
<span class='lineQuote level2'> P>> Exceptions"</span> ?
АГ> Там обсуждается немного другой аспект применения. АГ> На мой взляд, применение unchaught_exception в гуардах вполне кошерно. АГ> Каждый раз писать dismiss несколько утомительно, да и запросто забыть АГ> можно.
Во пример оттуда, ключевая фраза выделена жирным
Again, note that this doesn't do the right thing if a transaction is attempted in a destructor that might be called during stack unwinding:
// Example 19-3(a): Why the variant wrong solution
// is still wrong
//
U::~U() {
try {
Transaction t( /*...*/ );
// do work
} catch( ... ) {
// clean up
}
}
Андрей Галюзин wrote:
> На мой взляд, применение unchaught_exception в гуардах вполне кошерно. > Каждый раз писать dismiss несколько утомительно, да и запросто забыть можно.
Назначение гарда — всегда выполняться, независимо от того, было ли его деструктор вызван при раскрутке стека или при выходе из скопа. Поэтому для него unchaught_exception просто не нужно.
Здравствуйте, MaximE, Вы писали:
ME>Во первых, uncaught_exception() не реализован на MS VC++ (независимо от ситуации возвращает одно и тоже значение). Во-вторых, тебе может понадобиться отменить действие вручную.
Посмотрел сейчас сорцы, в 7.1 исправили этот досадный недочет,
_CRTIMP2 bool __cdecl uncaught_exception()
{ // report if handling a throwreturn (__uncaught_exception());
}
_STD_END
__uncaught_exception возвращает true, если есть любое активное SEH исключение, это и раньше было.