почему нельзя использовать uncaught_exception в dtor? - PullRequest
1 голос
/ 07 января 2011

Херб Саттер в своей статье http://www.gotw.ca/gotw/047.htm указал, что мы не можем использовать uncaught_exception в функции разрушителя,

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

Если объект U уничтожается из-за разматывания стека во время распространения исключения, T:: ~ T не сможет использовать путь «код, который может выбросить», даже если это безопасно.

, но я пишу тестовую программу, а T :: ~ T фактически не использовал «код»который может выбросить "

#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(...)
    {}
}

вывод: не может выбросить

я что-то пропустил?

Спасибо

1 Ответ

3 голосов
/ 07 января 2011

Это именно то, что он имел в виду: «не удастся бросить» означает «не бросит, потому что он будет думать, что бросание небезопасно в текущем контексте» ( not «произойдет сбой»; сбойзначит не будет)Поскольку деструктор вызывается как часть разматывания стека, вызванного исключением, std::uncaught_exception() возвращает true, а T::~T() не использует код, который может выдать (по его словам: T::~T не удастся использоватьпуть «код, который может выбросить», даже если он может безопасно ), потому что он думает, что он не должен выбрасывать.Дело в том, что поскольку T обернут в try{}catch(...){} блок , его можно бросить , даже если есть ожидающее исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...