Agreed. His examples are nonsensical, in almost every case comparing
handling an error in C with
signalling an error in C++. To see what I'm talking about, here's his first comparison:
// C
int rc = fx ();
if (rc != 0)
handle_error ();
// C++
int rc = fx ();
if (rc != 0)
throw std::exception ();
This is absurd. This is not the same thing in two different languages. These two pieces of code do two different things. One handles the error, and the other signals that there's an error that should be handled elsewhere. For an apples-to-apples comparison, let's consider both cases in each language. If this is the appropriate place to handle the error, then you handle it. It looks like this:
// C
int rc = fx ();
if (rc != 0)
handle_error ();
// C++
int rc = fx ();
if (rc != 0)
handle_error ();
I.e., exactly the same. If you DON'T want to handle the error here, then you return an error code or throw an exception:
// C
int rc = fx ();
if (rc != 0)
// There's no way to know where or whether this will be handled
return some_error_code;
// C++
int rc = fx ();
if (rc != 0)
// There's no way to know where or whether this will be handled
throw some_exception();
You're in the same boat in C and in C++. The error must be handled elsewhere, and nothing you do here can ensure that it will be. Exceptions have some advantages, though:
1. You do not have to anticipate inconvenient collisions between error return values and valid return values.
2. If the calling function is not the appropriate place to handle the error, then no boilerplate is required in the calling function to pass the error up the stack.
3. Exceptions let you use destructors instead of explicit cleanup blocks.
4. Failure to write error-handling code will not result in an operation proceeding in an invalid state, deceptively reporting success, or silently corrupting state. An error return value can simply be ignored. An unhandled exception will cause a cascading failure that cannot be mistaken for successful completion of an operation.
5. You can always use return values to report errors if they happen to be preferable in some cases.
P.S. The more I understand his complaints, the more I think he is just trying to get too fancy. If construction and destruction are problematic for some objects, then classes with trivial constructors and destructors give him exactly the struct-like behavior he wants, so what is wrong with that? How in the world do you get into worries about exceptions thrown from constructors and half-initialized objects (exception in the sense that any allocated-but-not-initialized struct is in a "half-initialized" state)? This is like saying knives are too dangerous to have the in the kitchen because you are in the habit of thrusting your hand blindly into the knife drawer.