有人告诉我何时调用terminate(),以及何时意外()?

时间:2013-03-16 13:05:06

标签: c++ exception terminate

当结束函数f()和g()时会发生什么?

#include<iostream>
using namespace std;

class A
{
     ~A(){}

}
void f()
{
    cout << "terminate" << endl;

}
void g()
{
    cout << "unexpected" << endl;
}



int main()
{
    set_terminate(f);
    set_unexpected(g);
    throw 5;
    cout << "end" << endl;
    return 0;
}

为什么叫abort()函数? 什么时候被称为destruktor?我找不到逻辑:((((((

2 个答案:

答案 0 :(得分:3)

  

任何人都可以告诉我何时调用terminate(),以及何时意外()?

在您的情况下,将调用您的终止处理程序。您可以验证here

关于std::terminate(),第15.5.1 / 1-2段包含一个注释,该注释列出了调用它的情况的详尽列表(粗体字的部分适用于您的情况):

  

1在某些情况下,必须放弃异常处理,以获得不那么微妙的错误处理技术。 [ 注意:   这些情况是:

     

- 当异常处理机制完成异常对象的初始化之后   但在激活异常处理程序(15.1)之前,调用通过异常退出的函数,   或

     

- 当异常处理机制无法找到抛出异常的处理程序(15.3)或

     

- 当搜索处理程序(15.3)遇到具有noexcept规范的函数的最外面的块时   不允许例外(15.4)或

     

- 在堆栈展开期间(15.2)通过抛出异常终止对象的销毁时,   或

     

- 当通过静态或线程存储持续时间(3.6.2)的非局部变量的初始化退出时   例外,或

     

- 当通过异常(3.6.3)或

退出具有静态或线程存储持续时间的对象时      

- 执行通过std::atexitstd::at_quick_exit注册的功能时,异常退出   (18.5),或

     

- 当没有操作数的throw-expression尝试重新抛出异常并且没有异常时   处理(15.1)或

     

- 当std::unexpected抛出先前违反的动态异常所不允许的异常时 -   规范和std :: bad_exception不包含在该动态异常规范中   (15.5.2),或

     

- 调用实现的默认意外异常处理程序(D.11.1)或

时      

- 为已捕获的对象调用函数std::nested_exception::rethrow_nested时   没有例外(18.8.6),或

     

- 执行线程的初始函数时,通过异常(30.3.1.2)或

退出      

- 在std :: thread类型的对象上调用析构函数或复制赋值运算符时   引用可连接线程(30.3.1.3,30.3.1.4)。    - 后注]

     

2在这种情况下,调用std::terminate()(18.8.3)。 [...]

关于std::unexpected(),根据第15.4 / 9段:

  

每当抛出异常并且搜索处理程序(15.3)遇到a的最外面的块时   函数具有不允许异常的异常规范,然后,

     

- 如果异常规范是动态异常规范,则函数std::unexpected()是   叫(15.5.2),

     

- 否则,调用函数std :: terminate()(15.5.1)。

答案 1 :(得分:1)

相关规则在标准中有明确规定,有许多规则但只是说并适用于你的例子:

    没有throw
  • catch会调用terminate或为其设置的函数。
  • 当抛出的异常与异常规范不匹配时,会导致调用unexpected或为其设置的函数。

15.1抛出异常
第8段:

  

如果当前没有处理异常,则执行不带操作数调用的throw-expression   terminate()(15.5.1)。

15.4例外规范
第8段:

  

每当抛出异常并且搜索处理程序(15.3)遇到a的最外面的块时   具有异常规范的函数,如果例外规范,则调用函数unexpected()(15.5.2)   不允许例外


  

为什么您的程序会调用abort

您的程序有一个未定义的行为。它符合以下事实:您正确设置terminate_handler,并且您注意到程序确实会调用f(),但terminate_handler函数所需的行为是:

C ++ 03标准18.6.3.1.2:

  

terminate_handler应终止程序的执行而不返回   给来电者。

您的terminate_handler函数f不满足此条件,因此导致未定义的行为,从技术上讲,您可能会获得任何行为,您的实现选择在此调用abort情况。没有什么能阻止它这样做。