Можно ли дважды ввести terminate_handler? - PullRequest
0 голосов
/ 24 августа 2010

У меня есть некоторая очистка в terminate_handler, и возможно выдать исключение. Нужно ли беспокоиться о его перехвате, чтобы предотвратить рекурсивные вызовы terminate_handler? С gcc кажется, что этого не может быть, и мы просто прерываемся. Это правда о стандарте или поведение не определено?

Ответы [ 2 ]

4 голосов
/ 24 августа 2010

Обработчик завершения не разрешен к возврату (§18.6. 3.1 / 2); он должен завершить программу (обработчик по умолчанию вызывает abort()). Если он состоял из:

void my_terminate()
{
    throw 5;
}

Вы получили бы неопределенное поведение, потому что вы оставили бы функцию (потому что исключение распространяется), не завершив программу. Поэтому, если у вас есть код, который может выдать, убедитесь, что вы перехватываете все исключения, например:

void my_terminate()
{
    try
    {
        // stuff
    }
    catch(...)
    {
        // too bad
    }

    abort();
}

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

void my_terminate()
{
    static int counter = 0;

    if (counter++ < 5)
        terminate();

    abort();
}
1 голос
/ 24 августа 2010

Нет, вы не можете возобновить нормальный поток программ с std::terminate. Вы можете , однако, выдает исключение из функции unexpected. Terminate делает именно это - выполнение программы прекращается после ее завершения.

EDIT:

Тем не менее, вы не должны делать ничего сложного в std::terminate - если вы в terminate, значит, все взорвалось настолько, что вы не должны пытаться продолжать - и вам не следует делать такие вещи, как выделение памяти в std::terminate по той же причине - что, если программа находится там из-за нехватки памяти? Там вы ничего не можете с этим поделать.

...