【问题标题】:Why the function unexpected is not called?为什么没有调用意外的函数?
【发布时间】:2014-10-13 17:51:31
【问题描述】:

我希望下面的代码调用我的 unexpected 处理程序,但我的 terminate 处理程序被调用了:

#include <except>
#include <iostream>

void my_terminate() {
    std::cerr << "my terminate handler";
    std::exit(0);
}

void my_unexpected() {
    std::cerr << "my unexpected handler";
    std::exit(EXIT_FAILURE);
}

#pragma argsused
int main(int argc, char* argv[])
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);
    try {
        throw std::exception();
    } catch (const std::logic_error&) {
    }
    return 0;
}

C++ Builder 6 Developer's Guide 明确鼓励通过set_unexpected() 安装自定义的意外处理程序。 我做错了什么,或者这只是 C++-Builder 6 中的错误?

【问题讨论】:

  • 如果你删除catch (const std::logic_error&amp;)会发生什么?
  • @stijn 你的意思是整个 try-catch 的事情?一样。

标签: c++ exception terminate c++builder-6


【解决方案1】:

通过调用std::set_unexpected(对于std::unexpected)设置的处理程序将在抛出意外异常时被调用;不是在未处理异常时。当违反动态异常规范时调用意外处理程序。

举例说明;

void my_terminate() {
    std::cerr << "my terminate handler";
    std::exit(0);
}

void my_unexpected() {
    std::cerr << "my unexpected handler";
    std::exit(EXIT_FAILURE);
}

void function() throw() // no exception in this example, but it could be another spec
{
    throw std::exception();
}

int main(int argc, char* argv[])
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);
    try {
        function();
    } catch (const std::logic_error&) {
    }
    return 0;
}

输出是

我意想不到的处理程序

std::set_terminate 设置的处理程序由std::terminate 调用(参考中列出的多种原因)。这里有趣的是,当异常被抛出但未被捕获时的默认行为是调用std::terminate

【讨论】:

  • 这是否意味着意外只处理异常规范?
  • @Wolf,我相信是的。当违反动态异常规范时调用它。见en.cppreference.com/w/cpp/error/unexpected
  • @Wolf:是的。 “预期”异常是与它要离开的函数的异常规范相匹配的异常。 “意外”异常是没有的异常。在您的示例中,异常是 unhandled 但不是 unexpected
  • 是否有特定的方法来检测未捕获的异常,或者terminate() 仅在致命情况下调用?
  • @Wolf,我认为terminate 很漂亮much it。如果未捕获到异常,则调用它。我不确定情况,但catch(...) 捕获所有异常...?
【解决方案2】:

当发生未捕获的异常时,调用terminate

int main()
{
    throw 1; // terminate
}

发生意外异常时,调用unexpected

void foo() throw(int)
{
    throw "unexpected will be called.";
}

int main()
{
    foo();
}

我将向您展示发生终止/意外的示例程序:

#include <cstdlib>
#include <iostream>
#include <exception>

#define TEST_TERMINATE

void my_terminate()
{
    std::cout << "terminate!" << std::endl;
    std::abort();
}
void my_unexpected()
{
    std::cout << "unexpected!" << std::endl;
    std::abort();
}

void foo() throw(int)
{
    throw "unexpected will be called.";
}

int main()
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);

#ifdef TEST_TERMINATE
    throw 1;
#else
    foo();
#endif
}

terminateunexpected 的实时示例)

【讨论】:

  • +1 这也回答了我作为评论添加到the first answer 的下一个问题。
  • ...但是terminate 是否只是因为这个原因而被调用?
  • @Wolf 根据http://en.cppreference.com/w/cpp/error/terminate 的说法,有10 个案例需要致电terminate
猜你喜欢
  • 2017-08-15
  • 2015-08-05
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多