我可以在std :: exception_ptr中修改异常的值吗? [英] May I modify the value of an exception inside a std::exception_ptr?

查看:172
本文介绍了我可以在std :: exception_ptr中修改异常的值吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I have a exception stored inside std::exception_ptr. I rethrow the exception using std::rethrow_exception, access it using catch(MyException&) and then I modify the value.

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

If I throw the same exception again, should I observe the modification I made?

以下代码演示我的想法:

The following code demonstrate my idea:

#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(),也可能不会引用同一个异常对象。

  • If you obtain your exception_ptr via current_exception(), it is unspecified whether you get a reference to a copy of the current exception, or a reference to the current exception itself. Even if you call current_exception() twice in a row, you may or may not get a reference to the same exception object.

由于 exception_ptr 是可复制的,并且副本可能指向相同的异常对象,而 rethrow_exception 不做一个副本,两个线程很可能同时抛出同一个异常对象。所以在一个多线程程序中,很难知道你是否有独特的访问 catch 子句中的异常。修改该异常可能会产生数据竞赛。数据竞赛可能存在于某些平台上,而不在其他平台上,具体取决于 current_exception()是否复制。

Since exception_ptr is copyable, and copies may point to the same exception object, and rethrow_exception doesn't make a copy, it is quite possible for two threads to throw the same exception object simultaneously. So in a multi-threaded program, it can be very difficult to know if you have unique access to an exception within a catch clause. Modifications to that exception may produce a data race. That data race may exist on some platforms, and not on others, depending on whether current_exception() makes a copy or not.

所以如果你必须修改多线程程序中的一个异常对象,最安全的是先复制它,修改副本,然后重新抛出副本(如果

So if you must modify an exception object in a multi-threaded program, it is safest to copy it first, modify the copy, and then rethrow the copy (if necessary).

更新

对不起,我给了一个不正确的答案。

Sorry, I have given an incorrect answer.

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

Using: http://webcompiler.cloudapp.net the output of the example code is:

0
0

rethrow_exception 的VS实现似乎会创建异常的副本。

The VS implementation of rethrow_exception appears to make a copy of the exception.

Clang和gcc不复制。

Clang and gcc do not make copies.

这篇关于我可以在std :: exception_ptr中修改异常的值吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆