Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

May I modify the value of an exception inside a std::exception_ptr?

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;
    }
}
like image 912
André Puel Avatar asked Jun 01 '15 18:06

André Puel


1 Answers

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.

like image 130
Howard Hinnant Avatar answered Sep 22 '22 13:09

Howard Hinnant