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:
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.
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).
UPDATE
Sorry, I have given an incorrect answer.
Using: http://webcompiler.cloudapp.net the output of the example code is:
0
0
The VS implementation of rethrow_exception
appears to make a copy of the exception.
Clang and gcc do not make copies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With