| Exploring Solution Spaces © Copyright 2003-2006, by C. Keith Ray | ||||||||||||||||||||||||
|
Archives
Subscribe |
2003.Oct.16 Thu Bill Caputo sums it up well: The real problem is bad coders. Joel says exceptions are just as bad as "Go To"s. What was the danger of "Go To"? Too many of them would make the control-flow hard to understand. The the whole point of "while", "do", "for", "break", "switch", "if/else if/else" and "return" was to allow changing the control-flow in easier to understand ways than "Go To". Of couse, over-usages of these can also make the control-flow hard to understand. In particular the following piece of code is just as bad a using "go to," and can be confusing if you expect "do...while" to loop. (This example doesn't loop.)
do
{
statements;
moreStatements;
if ( cond )
break; // equivalent of "go to"
otherStatements;
} while ( false ); // destination of "go to." Does NOT loop.
A "Go To" links a source point to a destination point -- this increases coupling between two points of the code. In C++, a "Go To" can be dangerous because it could skip initialization or destruction of local variables. What is the danger of exceptions? Too many of them can make the control-flow hard to understand -- but so can other control-flow statements. An exception does not link a source point to a destination point. It does not increase coupling between two points of code (generally speaking). In C++, the compiler (and the scope rules for try/catch) insures that throwing an exception does not skip initialization or destruction of local variables. The key point of using exceptions is to only use them for exceptional situations. If you're calling a search function, you expect to either find or not find find what you're searching for, so the search function should not be throwing an exception when something is not found (or when something is found). If the search function runs out of memory, an unexpected situation, then throwing an exception would be appropriate. Some place higher up the call-chain, perhaps in the user-interface code, should catch "out of memory" exceptions -- no matter who throws them -- and safely handle the situation. In the "old" days on MacOS pre-X, our "out of memory handler" would free up a reserve of memory, display a pre-fetched error alert, and then the user was in control again -- hopefully able to save and quit safely. I've seen very readable C code that used "setjump/longjmp" to do the same thing as throwing an exception -- to exit from any of several places, to an exception-handler, in the case of an unexpected or unrecoverable error situation. |
|||||||||||||||||||||||