使用未知对象捕获(...) - 如何识别抛出的内容?

时间:2017-11-30 11:16:04

标签: c++ exception exception-handling

我有一个我使用的库会抛出一些东西,但我不知道如何识别被抛出的东西。

重现此代码的示例代码:

int main()
{
    char* memoryOutOfBounds;
    unsigned __int64 bigNumber = -1;
    try {
        throw std::string("Test");
        memoryOutOfBounds = new char[bigNumber];
    }
    catch (const std::bad_alloc& ex)
    {
        printf("Exception: %s\n", ex.what());
    }
    catch (...)
    {
        printf("Unknown.\n");
    }

    return 0;
}

new char[bigNumber]会抛出一个std::bad_alloc,它来自std::exception并将进入第一个分支。另一个,throw std::string将进入第二个分支。如何检查抛出的对象?我试图使用catch(void*)希望捕获内存中的任何对象,但这没有发生,所以我怎样才能找出抛出的内容并从那里调试可能导致此问题的内容?

3 个答案:

答案 0 :(得分:2)

catch (...) {}

意味着:捕获绝对抛出的所有内容并将其丢弃。这只是一种保护措施,因此没有例外情况会飞出窗外并打倒整个房子。 (Aka:应用程序以非处理异常终止")

没有办法说出这里扔了什么。

但实际上你知道可以抛出一个std :: string,你可以在

中捕获它
catch (const std::string& s) {}

块。每当你想捕获异常时,你都需要知道抛出了什么(类型)。

但是,大多数为异常添加自己类型的库都会让它们继承自std :: exception。因此一个

catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
}
阻止应该得到它们。

如果他们没有继承std :: exception和/或阻止what()方法,那么使用它们的库变得非常困难是一种愚蠢的方式。

但是,在库的文档中的某处,应该解释异常抛出行为。

编辑:我认为第1点下面是&#34;我应该如何设计我的例外类&#34;在Boost Error Handling文档中,每个库开发人员都应该记住这一点。希望您图书馆的开发人员确实牢记这一原则。 ; - )

答案 1 :(得分:1)

确实没有标准的C ++方法来查询有关正在抛出的异常的任何信息。这是不幸的,因为运行时具有该信息以匹配catch块。但是用户代码中无法访问该信息。

如果它纯粹用于研究目的,比如只是找出类型是什么,因为您使用的库缺少文档,您可以使用std::current_exception()来获取std::exception_ptr在内部存储(或引用)抛出异常的对象。此类型是实现定义的,但您的调试器可能会为您提供足够的信息。

#include <exception>

void foo()
{
    try
    {
        function_that_throws();
    }
    catch(...)
    {
        std::exception_ptr p = std::current_exception();
        // break here and inspect 'p' with a debugger
    }
}

答案 2 :(得分:-1)

这个stackoverflow帖子会有所帮助 - C++ get description of an exception caught in catch(...) block

从C ++ 11开始,您可以使用指针捕获当前异常:

std::exception_ptr p;     // default initialization is to nullptr

try {
      throw std::string("Test");
}
catch(...)
{
     p = std::current_exception();
}