c++ - 如果异常保存在 std::exception_ptr 中,那么在 catch 语句之外使用异常是否安全?

标签 c++ exception c++11 exception-handling

我有一个 std::exception_ptr 里面有一个异常。我将调用 std::rethrow_exception 来获取实际的异常,异常在 catch 语句之后是否有效?我的猜测是因为我仍然持有 std::exception_ptr 它仍然有效。

看例子:

std::exception_ptr ePtr = initialize_somewhere_else();
std::runtime_error* a=NULL;
try {
    std::rethrow_exception(ePtr);
} catch(std::runtime_error& e) {
    a = &e;
}
std::cout << a << ", " << a->what() << std::endl;

注意:在我使用 Clang 的测试中,这确实有效。

最佳答案

Is it safe to use an exception outside the catch statement if it is held in a std::exception_ptr?

是的。您可以将 exception_ptr 视为指向异常的引用计数指针。只要 exception_ptr 引用它,异常就会存在,并且不再存在。

此外,rethrow_exception 不会复制。

抱歉,我想我的回答不正确。

这是一个检测测试:

#include <iostream>
#include <exception>
#include <stdexcept>


int
main()
{
    auto ePtr = std::make_exception_ptr(std::runtime_error("some text"));
    std::runtime_error* a = nullptr;
    try
    {
        std::rethrow_exception(ePtr);
    }
    catch(std::runtime_error& e)
    {
        a = &e;
    }
    *a = std::runtime_error("other text");
    try
    {
        std::rethrow_exception(ePtr);
    }
    catch(const std::runtime_error& e)
    {
        std::cout << e.what() << '\n';
    }
}

在 gcc 和 clang 上输出:

other text

这表明 aePtr 指的是完全相同的对象。

但是 VS,当前版本根据 http://webcompiler.cloudapp.net输出:

some text

这表明 aePtr 引用不同的对象。

现在的问题是VS是否符合这方面的要求。我的意见是这并不重要。这是该标准的一个有争议的领域,如果有争议,该标准将被更改以符合现有实践。

在我看来,rethrow_exception 在 VS 上进行了复制,这意味着不能保证原始问题中 e 的生命周期与 ePtr.

关于c++ - 如果异常保存在 std::exception_ptr 中,那么在 catch 语句之外使用异常是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30462906/

相关文章:

c++ - clear() 是否影响 std::unordered_set 的桶计数?

c++ - 混合使用 boost 锁和标准锁是否安全?

函数中的 C++ 函数?

python - 在 Python 2.6 中不推荐使用 BaseException.message

c++ - 有没有好的轻量级多平台C++定时器队列?

java - 检查外部长期 jar 是否成功启动的优雅方法

java - Flurry Agent 在 Android 2.3.4 上导致 CalledFromWrongThreadException 异常

c++ - 枚举类可以转换为基础类型吗?

C++11 "auto"到非 C++11 编译器

c++ - 如何将文本文件编译为 C++ 程序作为 const 字符串?