Thursday, May 20, 2004

Exceptions vs Return Codes

This is a response to my old Alpha Software co-worker Doug's recent post on the topic of Exceptions vs Return Codes. (It's actually funny to see Doug mention Ned - I don't know if Doug knows I used to work with Ned at Iris. Regardless they are two of the best developers I've worked with.)


Doug takes the Joel on Software position of favoring Return Codes and offers the following code snippet as an example of why return codes are better.



do { try {
if ((rc = tableCredits.open()) != OK) {
// log
break;
}
bUnwindTableCreditsOpen = TRUE;
if ((rc = tableCredits.lock()) != OK) {
// log
break;
}
bUnwindowTableCreditsLock = TRUE;
if ((rc = tableDebits.open()) != OK) {
// log
break;
}
bUnwindTableDebitsOpen = TRUE;
if ((rc = tableDebits.lock()) != OK) {
// log
break;
}
bUnwindowTableDebitsLock = TRUE;
if ((rc = ::IntegralTransaction(tableCredits, tableDebits, curAmount)) != 0) {
// log
break;
}
} catch (...) {
// catch miscellaneous exceptions here
} } while (0);
if (bUnwindTableDebitsUnlock) {
tableDebits.unlock();
}
if (bUnwindTableDebitsOpen) {
tableDebits.close();
}
if (bUnwindowTableCreditsLock) {
tableCredits.unlock();
}
if (bUnwindTableCreditsOpen) {
tableCredits.close();
}
return (rc);


Using Java with exceptions I could write this code just as safely with:



try {
tableCredits.open();
bUnwindTableCreditsOpen = true;
tableCredits.lock();
bUnwindowTableCreditsLock = true;
tableDebits.open();
bUnwindTableDebitsOpen = true;
tableDebits.lock();
bUnwindowTableDebitsLock = true;
IntegralTransaction(tableCredits, tableDebits, curAmount);
}
finally {
if (bUnwindTableDebitsUnlock) {
tableDebits.unlock();
}
if (bUnwindTableDebitsOpen) {
tableDebits.close();
}
if (bUnwindowTableCreditsLock) {
tableCredits.unlock();
}
if (bUnwindTableCreditsOpen) {
tableCredits.close();
}
}

If it was Doug's intention to only close the resources when a failure occured that's easy too



boolean unwind = false;
try {
tableCredits.open();
bUnwindTableCreditsOpen = true;
tableCredits.lock();
bUnwindowTableCreditsLock = true;
tableDebits.open();
bUnwindTableDebitsOpen = true;
tableDebits.lock();
bUnwindowTableDebitsLock = true;
IntegralTransaction(tableCredits, tableDebits, curAmount);
} catch (SomeException e) {
unwind = true;
throw e;
}
finally {
if (unwind) {
if (bUnwindTableDebitsUnlock) {
tableDebits.unlock();
}
if (bUnwindTableDebitsOpen) {
tableDebits.close();
}
if (bUnwindowTableCreditsLock) {
tableCredits.unlock();
}
if (bUnwindTableCreditsOpen) {
tableCredits.close();
}
}
}

So perhaps Doug's point is more an indictment of C++ than of exceptions in general.
Post a Comment
 
The Out Campaign: Scarlet Letter of Atheism