I was reading Google C++ Style Guide, and got confused in the Exceptions part. One of the cons of using it, according to the guide is:
Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth
Specifically, the statement that I didn't understand is this:
(...) exception-safe code must isolate logic that writes to persistent state into a "commit" phase.
and this:
(...) perhaps where you're forced to obfuscate code to isolate the commit (...).
I think I'm not used to the terms "persistent state", "commit phase", "obfuscate code to isolate the commit". It'd be nice some small explanations, examples or references about these terms and possibly why this is true.
Using exceptions for error handling has two disadvantages. First, exceptions can trap only runtime errors. Therefore, a PL/SQL program cannot trap and recover from compile-time (syntax and semantic) errors such as table or view does not exist.
Exception handlers have disadvantages. If a function does not return because it, or some other function it called, threw an exception, data might be left in an inconsistent state. You need to know when an exception might be thrown, and whether the exception might have a bad effect on the program state.
error codes. Exceptions separate error-handling code from the normal program flow and thus make the code more readable, robust, and extensible. Throwing an exception is the only clean way to report an error from a constructor. Exceptions are hard to ignore, unlike error codes.
What is the advantage of exception handling ? Remove error-handling code from the software's main line of code. A method writer can choose to handle certain exceptions and delegate others to the caller. An exception that occurs in a function can be handled anywhere in the function call stack.
Basically, modern C++ uses Scope-Bound Resource Management (SBRM, or RAII). That is, an object cleans up a resource in its destructor, which is guaranteed to be called.
This is all fine and dandy, unless your code isn't modern. For example:
int *i = new int();
do_something(i);
delete i;
If do_something
throws an exception, you've leaked. The correct solution is to not have the resource out in the wild like that, i.e.:
std::auto_ptr<int> i(new int());
do_something(i.get());
Now it can never leak (and the code is cleaner!).
I think what the guide is trying to say is that we already have all this old code, and using a modern style would take too much effort. So let's not use exceptions. (Rather than fix all the code...I dislike the Google Style Guide very much.)
"writes to persistent state" mean roughly "writes to a file" or "writes to a database".
"into a 'commit' phase." means roughly "Doing all the writing at once"
"perhaps where you're forced to obfuscate code to isolate the commit" means roughly "This may make the code hard to read" (Slight misuse of the word "obfuscate" which means to deliberately make something hard to read, while here they mean inadvertantly make it hard to read, but that misuse may have been intentional, for dramatic effect)
Elaborating more: "writes to persistent state" more closely means "Write out, to some permanent media, all the details about this object that would be needed to recreate it". If writing was interrupted by an exception, then those "written out details" (i.e. "persistent state") could contain half the new state and half the old state, leading to an invalid object when it was recreated. Hence writing the state must be done as one uninterruptable act.
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