If I use an expression that may throw to assign a value to a variable of fundamental type, is it guaranteed that the state of the variable is unaltered if an exception is thrown?
For instance, in the following code, if we choose 'Option A' and an exception is thrown by operator new()
, is there any chance that the member variable ptr
will not be equal to nullptr
when the destructor will be called during the stack unwinding?
#include <new> // operator new operator delete
class MemoryHolder {
private:
void * ptr;
public:
MemoryHolder () {
ptr = nullptr;
}
void increase_memory () {
operator delete (ptr);
ptr = nullptr;
// Option A (unsafe?)
ptr = operator new (10);
// Option B (safe)
void * new_ptr = operator new (10);
ptr = new_ptr;
}
~MemoryHolder () {
operator delete (ptr);
}
};
I am interested to know the answer for both C++14 and C++17.
My guess: 'Option A' is safe in C++14 and C++17 because they both contain this statement (cf. § [expr.ass] ¶ 1):
In all cases, the assignment is sequenced after the value computation of the right and left operands
However, I am not sure that performing the 'value computation' of the left operand doesn't include giving it its new value. I did not find a definition of 'value computation' in the standard.
Related (but unclear to me): Assignment in C++ occurs despite exception on the right side