Advice article scopeguard was
In the area of ββexceptions, itβs crucial that you canβt do anything if your undo / redo action is not performed. You are trying to perform a cancel operation, and you are moving whether the cancel operation is successful or not.
It may seem crazy, but think:
- I manage to run out of memory and get a
std::bad_alloc - My cleanup code logs an error
- Unfortunately, the recording failed (the disk may be full) and is trying to throw an exception
Can I cancel a journal entry? Should I try?
When an exception is thrown, all you really know is that the program is in an invalid state. You should not be surprised that some impossible things are possible in the end. Personally, I have seen many more cases where Alexandrescu's advice makes the most sense than otherwise: try to clean it up, but admit that the first exception means that things are already in an unacceptable state, so additional crashes - especially crashes caused by the first problem (" cascade of errors ") - should not be a surprise. And trying to cope with them will fail. [/ P>
I should probably mention that Cap'n Proto does exactly what you suggested:
When Capn Proto code can throw an exception from the destructor, it first checks std::uncaught_exception() to make sure it is safe. If another exception is already active, the new exception is considered a side effect of the main exception and is either tacitly swallowed or reported on the side channel.
But, as Jakk said, destructors became nothrow(true) by default in C ++ 11. This means that if you want to do this, you must be sure that in C ++ 11 and later you mark the destructor as nothrow(false) . Otherwise, an exception from the destructor excludes the program, even if there is no other exception in flight. And note: "If another exception is already active, the new exception is considered a side effect of the main exception and is either tacitly swallowed or reported on the side channel."
source share