代码之家  ›  专栏  ›  技术社区  ›  Wolf

为什么未调用意外函数?

  •  6
  • Wolf  · 技术社区  · 10 年前

    我希望以下代码调用 想不到的 处理程序,但我的 终止 而是调用处理程序:

    #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++Builder6中的一个bug?

    2 回复  |  直到 10 年前
        1
  •  13
  •   Niall    10 年前

    调用设置的处理程序 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::终止 .

        2
  •  4
  •   ikh    10 年前

    当发生未捕获的异常时, 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
    }
    

    (实时示例 terminate , unexpected )

    推荐文章