camino
camino

Reputation: 10584

why cannot use uncaught_exception in dtor?

Herb Sutter in his article http://www.gotw.ca/gotw/047.htm pointed out that we cannot use uncaught_exception in desturctor function,

//  Why the wrong solution is wrong
//
U::~U() {
  try {
    T t;
    // do work
  } catch( ... ) {
    // clean up
  }
}

If a U object is destroyed due to stack unwinding during to exception propagation, T::~T will fail to use the "code that could throw" path even though it safely could.

but I write a test program, and T::~T in fact didn't use the "code that could throw"

#include <exception>
#include <iostream>
using namespace std;

class T {
  public:
  ~T() {
  if( !std::uncaught_exception() )
  {
    cout<<"can throw"<<endl;
    throw 1;
  } else
  {
    cout<<"cannot throw"<<endl; 
  }
}


};

struct U
{
~U() {
  try 
  {
    T t;
  }
  catch( ... ) 
  {
  }
}
};

void f()
{
  U u;
  throw 2;
} 

int main()
{
    try
    {
      f();
    }
    catch(...)
    {}
}

output is : cannot throw

did I miss something?

Thanks

Upvotes: 1

Views: 300

Answers (1)

conio
conio

Reputation: 3718

This is exactly what he meant: "will fail to throw" means "will not throw because it will think that throwing isn't safe in the current context" (not "will crash"; fail here means won't happen). Because the destructor is called as part of the stack-unwinding caused by an exception std::uncaught_exception() returns true, and T::~T() doesn't use the code that might throw (in his words: T::~T will fail to use the "code that could throw" path even though it safely could) because it thinks that it shouldn't throw. The point is that because T's wrapped in a try{}catch(...){} block it is safe to throw, even though there's a pending exception.

Upvotes: 3

Related Questions