我可以修改 std::exception_ptr 内的异常值吗?

2024-03-14

如果我里面存储了异常std::exception_ptr。我使用重新抛出异常std::rethrow_exception,使用访问它catch(MyException&)然后我修改该值。

如果我再次抛出相同的异常,我应该观察我所做的修改吗?

下面的代码演示了我的想法:

#include <exception>
#include <iostream>

struct MyException {
    int value;
};

int main() {
    std::exception_ptr a = std::make_exception_ptr(MyException());

    try {
        std::rethrow_exception(a);
    } catch(MyException& b) {
        std::cout << b.value << std::endl;
        b.value = 3;
    }

    try {
        std::rethrow_exception(a);
    } catch(MyException& b) {
        std::cout << b.value << std::endl;
    }
}

Your code is conforming and portable. But there be dragons here:

  • 如果您获得您的exception_ptr via current_exception(),未指定您是否获取对当前异常副本的引用,或对当前异常本身的引用。即使你打电话current_exception()连续两次,您可能会也可能不会获得对同一异常对象的引用。

  • Since exception_ptr是可复制的,并且可以复制may指向同一个异常对象,并且rethrow_exception不进行复制,两个线程很可能同时抛出同一个异常对象。因此,在多线程程序中,很难知道您是否具有对某个异常的唯一访问权限。catch条款。对该异常的修改可能会产生数据争用。这种数据竞争可能存在于某些平台上,而不存在于其他平台上,具体取决于是否存在current_exception()是否复印。

因此,如果必须在多线程程序中修改异常对象,最安全的做法是先复制它,修改该副本,然后重新抛出该副本(如果需要)。

UPDATE

抱歉,我给出了错误的答案。

Using: http://webcompiler.cloudapp.net http://webcompiler.cloudapp.net示例代码的输出是:

0
0

VS 的实现rethrow_exception似乎复制了异常。

Clang 和 gcc 不复制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以修改 std::exception_ptr 内的异常值吗? 的相关文章

随机推荐