Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Throw exception by value or reference

From this answer https://stackoverflow.com/a/36738405/4523099 :

A throw-expression with no operand rethrows the currently handled exception. The exception is reactivated with the existing temporary; no new temporary exception object is created. -- ISO/IEC 14882:2011 Section 15.1 par. 8

So why I am getting this results from this code?

code:

#include <iostream>

class my_exception: public std::exception{
public:
    int value;
};
int main()
{
    my_exception ex;
    ex.value=1;
    try{
        throw ex;
    }
    catch(my_exception& e){
        e.value=2;
    }
    std::cout << ex.value;
   return 0;
}

Actual result:

1

I thought it should be 2 depending on the standard quota. What am I missing?

like image 533
Humam Helfawi Avatar asked Jan 06 '23 05:01

Humam Helfawi


2 Answers

This is beacuse throw (the regular version) will make a copy :

First, copy-initializes the exception object from expression (this may call the move constructor for rvalue expression, and the copy/move may be subject to copy elision), ...

and keep it internally, so e.value=2; modifies internal copy.

In the SO you mention question was about the re-throw version witch does not make a new copy but uses the already existing internal copy.

like image 100
marcinj Avatar answered Jan 14 '23 13:01

marcinj


It's only the re-throw (with no operand) that re-uses the same exception object. Here's some code to demonstrate that:

#include <iostream>

class my_exception: public std::exception{
public:
    int value;
};

void f(my_exception& ex) {
    ex.value = 1;
    try {
        throw ex;
    } catch (my_exception& e) {
        e.value = 2;
        // Here's the re-throw
        throw;
    }
}

int main()
{
    my_exception ex;
    try {
        f(ex);
    } catch (my_exception& e) {
        std::cout << e.value;
    }
    return 0;
}
like image 30
Toby Speight Avatar answered Jan 14 '23 14:01

Toby Speight