【问题标题】:Is it possible to enter the terminate_handler twice?是否可以输入 terminate_handler 两次?
【发布时间】:2010-08-24 07:14:50
【问题描述】:

我在 terminate_handler 中进行了一些清理,并且有可能引发异常。我是否需要担心捕获它以防止对 terminate_handler 的递归调用?使用 gcc,这似乎不可能发生,我们只是进入中止。标准是这样还是行为未定义?

【问题讨论】:

  • 我认为这不会有帮助作为答案,但是在此期间是否可以不做任何可能引发异常的事情?
  • 在 terminate_handler 中,我试图完成一些日志缓冲区的消耗。只要程序终止,我不妨看看我能从日志缓冲区中得到什么。如果它失败了,它就失败了,但为什么不尝试呢?我只是担心如果记录器进入它开始抛出的状态会出现很大的倒退。

标签: c++ terminate


【解决方案1】:

终止处理程序不允许返回(§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();
}

【讨论】:

  • std::terminate -- 可能只有catch (...) 还可以。 +1
【解决方案2】:

不,您无法从std::terminate 恢复正常的程序流程。但是,您可以抛出与unexpected 函数不同的异常。 Terminate 就是这样做的——程序执行完成后终止。

编辑:

也就是说,你不应该在 std::terminate 中做任何复杂的事情——如果你在 terminate 中,那么事情已经严重到你不应该继续尝试的程度——而且你不应该尝试出于同样的原因在std::terminate 中分配内存 - 如果由于内存不足而导致程序在那里怎么办?在那里你无能为力。

【讨论】:

  • 我不想恢复正常的程序流程。我的处理程序可能看起来像这样 void myTerminate(){ logger.consumeAll(); }。这是最后一次尝试记录那里的内容。我想知道如果 Logger::consumeAll 抛出会发生什么。
  • @Pythonic:是的,我只是在解释我的意思方面做得不好。如果这就是你正在做的,正如 GMan 所说,如果它抛出你有未定义的行为。
  • @pythonic:哦,仅仅因为您不想要恢复正常的程序流程,并不意味着如果您不这样做,您就不会这样做从std::terminate 扔掉;)
  • 直到阅读回复后,我才明白最后一点!
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多