Как я могу определить, активно ли исключение во время деструктора? - PullRequest
1 голос
/ 01 ноября 2011

В C ++, как я могу обнаружить в теле моего деструктора, разворачивается ли стек из-за генерируемого исключения? Могу ли я получить ссылку на активное исключение после обнаружения?

Я спрашиваю, потому что я хотел бы добавить некоторый код отладки, который объясняет, почему может возникнуть определенная ситуация и связана ли она с исключениями.

Ответы [ 4 ]

4 голосов
/ 03 ноября 2011

std::uncaught_exception сообщает, разматывается ли стек из-за создаваемого исключения, о чем вы и просили.

Однако это не говорит вам о том, что вы, вероятно, хотите знать: находится ли объект, от деструктора которого вы его вызываете, в той части стека, которая разматывается, или в той части стека, которая обычно уничтожается из-за чтобы без исключения выйти из области видимости под каким-то другим деструктором, который является частью раскрутки:

struct A {
    ~A();
};

struct B {
    ~B();
}

int main() {
    try {
        A a;
        throw 1;
    } catch(...) {}
}

A::~A() {
    std::uncaught_exception(); // true
    B b;
}

B::~B() {
    std::uncaught_exception(); // also true, but "b" isn't being "unwound",
      // because ~A() returned, it didn't throw.
}

Вопреки тому, что говорят DeadMG и Xeo, вы не можете получить ссылку на исключение, которое не было обнаружено. throw без операнда сбрасывает «текущее обработанное исключение», то есть исключение, в обработчике которого вы находитесь или чей-обработчик вызвал вас. Это не отбрасывает неисследованное исключение.

0 голосов
/ 07 августа 2018

А как насчет новых C100 17 std::uncaught_exceptions()?Я думаю, что вы можете создать код, который выглядит следующим образом:

class ExceptionSentinel
{
    int prev_uncaught;

public:
    ExceptionSentinel() : prev_uncaught(std::uncaught_exceptions()) {}

    ~ExceptionSentinel()
    {
        int cur_uncaught = std::uncaught_exceptions();
        if (cur_uncaught > prev_uncaught)
        {
            // ... ExceptionSentinel is being destructed by an stack unwinding process
        }
        else
        {
            // ... Normal destruction of ExceptionSentinel
        }
    }
};

В этом случае std::uncaught_exceptions() отслеживает число необработанных исключений к моменту вызова кода.Больше информации можно найти на странице cppreference .

0 голосов
/ 01 ноября 2011

Есть функция std::uncaught_exception().Однако, единственная полезная вещь, которую вы можете сделать, чтобы попытаться получить доступ к объекту исключения, - это сбросить его и попытаться его поймать.Вы никогда не должны выбрасывать исключения из какого-либо деструктора.

0 голосов
/ 01 ноября 2011

В C ++, как я могу обнаружить в теле моего деструктора, разворачивается ли стек из-за создаваемого исключения?

нет.

После обнаружения я могу получить ссылку на активное исключение?

Количество

...