views:

207

answers:

4

In a destructor, is there a way to determine if an exception is currently being processed?

+5  A: 

You can use std::uncaught_exception(), but it might not do what you think it does: see GoTW#47 for more information.

Luc Touraille
A: 

You can use again BOOST with library Boost Test Library Look here for an small example :
struct my_exception1
{
explicit my_exception1( int res_code ) : m_res_code( res_code ) {}
int m_res_code;
};

struct my_exception2
{
explicit my_exception2( int res_code ) : m_res_code( res_code ) {}
int m_res_code;
};

class dangerous_call {
public:
dangerous_call( int argc ) : m_argc( argc ) {}
int operator()()
{
if( m_argc < 2 )
throw my_exception1( 23 );
if( m_argc > 3 )
throw my_exception2( 45 );
else if( m_argc > 2 )
throw "too many args";

return 1;
}

private:
int m_argc;
};

void translate_my_exception1( my_exception1 const& ex )
{
std::cout << "Caught my_exception1(" << ex.m_res_code << ")"<< std::endl;
}

void translate_my_exception2( my_exception2 const& ex )
{
std::cout << "Caught my_exception2(" << ex.m_res_code << ")"<< std::endl;
}

int
cpp_main( int argc , char *[] )
{
::boost::execution_monitor ex_mon;
ex_mon.register_exception_translator(&translate_my_exception1);
ex_mon.register_exception_translator(&translate_my_exception2);
try{
// ex_mon.detect_memory_leak( true);
ex_mon.execute( ::boost::unit_test::callback0( dangerous_call(
argc ) ) );
}
catch ( boost::execution_exception const& ex ) {
std::cout << "Caught exception: " << ex.what() << std::endl;
}
return 0;
}

You have to dig in the documentation ...is a very powerful library to testy your software ! Anyway with the help of boost you can catch any kind of exception trigerred anywhere in your function test !

Eddie
Of course your test function can be inside to a struct where you overload the () operator...and there you can put your test to see what exception is generated
Eddie
Suggestion: your code example will be much easier to read if you use the 'code sample' format (the ones-and-zeros button in the answer editor) to wrap it.
jwfearn
+2  A: 

This smells suspicious. Why would you want to a different kind of cleanup if an exception occurred?

Pramod
Agreed Suspicious. And you never want to throw out of a destructor IMO. But you can throw from a destructor, BUT if you throw from a destructor while another exception is propagating the application will terminate (without exiting or normal cleanup)
Martin York
+2  A: 

As Luc said, you can use std::uncaught_exception(). But why do you want to know? In any case, destructors should never throw exceptions!

Xavier Nodet
Yep, smells of trying to avoid ending up in terminate() by not throwing when already unwinding.
Mike Dimmick