【发布时间】:2015-02-27 03:43:50
【问题描述】:
以下程序的定义行为是什么?
#include <iostream>
#include <exception>
#include <cstdlib>
void i_throw()
{
std::cout << "i_throw()" << std::endl;
// std::terminate() is noexcept so if the terminate handler throws...
// then the terminate handler is called...
// std::terminate is [[noreturn]] so don't return
try
{
throw 7;
}
catch(...)
{
std::cout << "caught exception, re-throw()-ing" << std::endl;
throw;
}
std::cout << "got here!" << std::endl;
std::abort();
}
int main()
{
std::set_terminate(i_throw);
throw;
std::terminate();
}
使用 gcc 和 clang 我得到以下输出:
i_throw()
caught exception, re-throw()-ing
Aborted (core dumped)
在前几个 cmets 后编辑的示例。
(我不知道为什么我同时拥有throw; 和std::terminate();。我不想更改示例,所以就假装只有这两者之一。)
【问题讨论】:
-
这个程序导致无限递归。与任何其他无限递归一样,它最终会由于耗尽实现的资源限制(1.4/(2.1))而异常结束。请注意,这里没有抛出异常,
terminate的noexcept规范是无关紧要的。在没有操作数的情况下执行throw;,同时没有处理异常调用terminate()(5.17/4) -
@IgorTandetnik 我想我在您的评论中看到了答案。您能否澄清一下没有抛出异常是什么意思?
-
终止处理程序需要终止程序的执行。你的没有。
-
@T.C.但它会。这是否意味着有效的终止处理程序不能允许异常冒泡?
-
@Praxeolitic 1) 代码中有一条注释表明 OP 认为有一个异常被抛出,并且对
terminate()的调用是由该异常向上和向外传播引起的terminate和后者是noexcept。但是throw;不带参数只会在当前正在处理异常时抛出异常;否则,它只是直接调用terminate。后一种情况实际上发生在示例中。
标签: c++ exception language-lawyer terminate-handler