Fog Creek Software
Discussion Board




finally, exceptions == bad

While writing some applications recently, I am positive that I had Joel’s exact thought, but it was stuck in my subconscious.

His article brought it to the surface; it was like coming out of a dark room. 

Thanks for the light Mr. Sposky. Now at least I know WHY I hate exceptions.

Now I am on to rewriting all of my code to not use user generated, just kidding… I will “refactor” next year.

--
ee

eclectic_echidna
Monday, October 13, 2003

Kudos to Joel for speaking his mind and not being afraid to buck tradition.

That said, I disagree profoundly with his stance.

Most of the arguments *for* exceptions have already been made, eg here:

http://c2.com/cgi/wiki?UseExceptionsInsteadOfErrorValues

Portabella
Monday, October 13, 2003

When I first started using exceptions I had the same reaction as Joel. But over time I've found some advantages to the exception model and now I use them when the language implements them.

Some points Joel missed:

A thrown exception is a kind of goto, but it's more than that. Exceptions include state information--they aren't just an unconditional transfer of control. And while you can't look at the source code and predict where an exception might be thrown, you can't look at source code and predict where it will crash or return a bad result, either, so exceptions are making the code more obscure. Code will contain errors regardless of whether exceptions are used or not; exceptions just give you a way to catch and handle them in a defined and orderly way.

Explicitly returning error codes creates multiple problems we've all seen in C and other languages. Different authors and libraries use different conventions. Should the error code be a number, or a string, or an object? How about putting the last error code in a global (a la Visual Basic)? Programmers tend to not write error handling code. We might check the return value from open() but not from malloc(), for example; many times I've heard (and said) "If that fails the program is dead anyway, so why check the return code?"

As Joel pointed out returning error codes from functions makes them hard to use and clutters up the source with error handling; exception-based code separates the meat from the potatoes and moves the error handling code nearby but out of the way.

You can ignore or pass exceptions, but you have to deal with error codes on the spot, or propagate them up the call chain and fill your code with if/else or (horror) return or goto. Propagating error codes back up the call chain twists the code into knots and increases module coupling. If you're four functions down and discover an error that has to generate a message to the user, you have to communicate that up the call chain. We've all seen the mess of propagating error codes; exceptions make this go away and let you put the error handling code at a level where the code is prepared to handle the error.

Exceptions reduce module coupling because any module can simply ignore (not catch) exceptions and let them pass to its caller. Error codes must be explicitly examined and propagated, which means each module must know the type and values of the codes. Mix in some third-party libraries and you see the problems multiply.

Exceptions are language features, not programmer conventions. Most languages that implement exceptions define a core set of exceptions and provide for additional or subclassed exception types, using (one hopes) familiar OOP techniques. Because they are (usually) objects, exceptions can use inheritance and carry arbitrary state information. Using exception classes defined in the language is probably preferable than everyone making up their own error reporting scheme--just look at the differences between the old ANSI C libraries and MFC.

Exceptions fit more naturally with event-driven programming, especially at the interface between the code running the event loop and the functions/modules underneath.

There was a dicussion recently in a Python newsgroup about when to use exceptions and whether it's OK to raise exceptions instead of using if/else. The answer is, it depends on which version is most clear. I don't usually have occasion (in Python) to raise exceptions, but one application--a web server that calls multiple screen scrapers where anything can happen while scraping the virtual VT100 screen--makes extensive use of exceptions. No matter what goes wrong at the low level, the correct action is (a) give the user a friend error message, and (b) restart the FSM running the scraper and restart the telnet connection. And, by the way, Python allows functions to return multiple values (as a tuple), but that doesn't really help much with the problems I've already described.

You don't have to use exceptions--you can ignore them and let the code above your app (the shell, web server, or OS) catch them and dump a generic error message. At minimum exceptions let your whole application stop, gracefully or not, rather than humming along breaking things because someone forgot to check a returned error code.

Rather than simply dismiss exceptions as bad, recognize that exceptions are not simple language constructs like the goto statement, and can often enhance the robustness, readability, and transportability of your code.

Gregory Jorgensen
Monday, October 13, 2003

Joel, I hardly ever react to anything you write with anything other than a satisfied ‘aaah’ as I experience surprise and enlightenment. But I take exception to your remarks about exceptions.

I don’t understand how you can think that giving up structured exception handling could be anything other than a reversion to the dark ages. “Finally” ;-) we can deal with certain exception conditions in one place in our code instead of having to trap these things all over the place. Finally (in .NET) we have rich metadata about stuff that goes wrong and debugging is therefore greatly simplified. HRESULTs, properly used, are a good thing, but they don’t hold a candle to this.

I like to think of exceptions as a kind of out-of-band signalling. A little like the audible tones that allowed the Captain Crunch to phreak the long-distance telephone system, HRESULTs and other return-value-based exception management practices simply get in the way of readable code—the nominal case that can be difficult enough to understand if the flow of the source is constantly interrupted by superfluous error-checking. You can also ignore the exception information in resturn values with a lot less sirens going off. I realize that bulletproof code is usually replete with localized exception handling, but why complicate matters by forcing every imaginable exception to be handled locally, over and over again? I think Martin Fowler’s advice is applicable here: “The code says everything once and only once, which is the essence of good design.” Kent Beck would also agree, if I may be so bold.

Nils Jonsson
Monday, October 13, 2003

We had this discussion before.

http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=3106

Alyosha`
Monday, October 13, 2003

I honestly read Joel's rant as "exceptions are new and different and I don't like them."

Philo

Philo
Monday, October 13, 2003

Without trying to troll, after reading Joel's little bit on exceptions, my first reaction is "If anyone else in Microsoft thinks this way, no wonder their code is full of security holes".

The problem with return codes is it's just SO easy to forget to check them. You forget to check a return code even once, and you've got a big fat hole in your program. Maybe you'll never notice it. But chances are one day the call will fail, and when it does, who knows what the hell might happen.

It may just cause a crash. It may just cause part of the program to fail. Or it may bypass some security check, or open up a valnerability for people to attack. You can't know ahead of time.

With exceptions, at least you know what happens if you don't handle them - they propogate to the next level. This means the absolute worst thing that can happen by not handling them is the exception reaches the top level of your code and it crashes out. Not ideal, but a hell of a lot better than the previous option.

Another problem with error codes is that they're very good for local handling of errors, but horrible for handling remote errors. It's OK if the function you've jsut called returns an error code - you can easily tell what went wrong. But by the time you've passed that 5 levels down the call stack, you've lost the context. Exceptions capture that context.

OO code pretty much demands exceptions or else it gets damn ugly too. Without exceptions, your return code is useless - you need it for error reporting. Consider these two options for using MSXML's DOM to get an attribute value, assuming xmlNode is a IXMLDOMNode pointer representing an element:

_bstr_t val = xmlNode->attributes->getNamedItem(L"blah")->nodeValue;

IXMLDOMNamedNodeMapPtr attrs;
HRESULT hr = xmlNode->get_attributes(&attrs);
if (FAILED(hr))
    // handle error

IXMLDOMNodePtr attr;
hr = xmlNode->getNamedItem(L"blah", &attr);
if (FAILED(hr))
    // handle error

_bstr_t val;
hr = xmlNode->get_nodeValue(&val);
if (FAILED(hr))
    // handle error

Now I know which one I prefer to read, and to write, and to debug, and to maintain! :)

Constructors are rather problematic too. They can't return values - so you pretty much have to throw an exception to indicate you couldn't construct the object.

That's not to say exceptions are a panacea. They do have performance issues if you're throwing too many of them. They are a pain for the less common case where you WANT to ignore and error. It is difficult to know when exceptions will occur - people often forget that just about anything can potentially throw an exception, so you should plan accordingly.

But in general, if given the choice, I'd take exceptions over no exceptions any day.

Sum Dum Gai
Monday, October 13, 2003

Like many, I respectfully make a rare disagreement with Joel here.

In Java, the code to catch exceptions is required to be entered at compile time.  This enforces the user to include proper error handling, which is much better than optionally handled ambiguous, user-defined error codes.  (the programmer can include a generic Exception catch clause at the end of a method, but good practice encourages a catch clause for each separate Exception).

(I'm not a C++ programmer; can someone comment if the language syntax is this strict?)

The alternate case (no pun here!) is subclasses of RunTimeException and Error, which do not require a catch clause.  (Exceptions are just automatically propagated up the call stack).  I think it's poor practice to use these; most of the Java class library avoids them.

Will
Monday, October 13, 2003

So let's assume exceptions are to be considered harmful. Here are a few numbers from different JDK versions, all to be treated as LOC:

try {} statements:
  JDK 1.02 - 93
  JDK 1.22 - 507
  JDK 1.40 - 2143

catch {} statements:
  JDK 1.02 - 108
  JDK 1.22 - 909
  JDK 1.40 - 3505

throw new statements:
  JDK 1.02 - 167
  JDK 1.22 - 2011
  JDK 1.40 - 6700

According to your logic, Joel, Sun's developer staff has been constantly exchanged by newbies/monkeys/nuts. Others would argue the JDK constantly increased in quality and safety.

Johnny Bravo
Monday, October 13, 2003

I must say also, this is first thing I strongly disagree with Joel on.  I do abhor checked exceptions as the ivory tower approach.  But unchecked exceptions make code far easier to write and read.  I think the following discussion on exceptions, especially on the using finally rather than catch: http://www.artima.com/intv/handcuffs.html

Mike
Monday, October 13, 2003

I also read Joel's post with disblief. How anyone with any experience of modern programming could consider exceptions a bad thing just amazes me. Certainly there are debates about checked vs unchecked exceptions but to want to remove exceptions completely is ridiculous. Far from being a form of strange GOTO the exceptions that a method may throw are important part of the contract the method exposes while avoiding cluttering up the code with easy to forget return code checks. You might as well call for a return of the ALTER GOTO statement.

Alex
Monday, October 13, 2003

Joel's site must have been hacked.  Either that or he's being sarcastic.

T. Norman
Monday, October 13, 2003

Joel's position is really quite odd.  Consider the alternatives:

With exceptions, if you don't want to shoot control back to the caller, you put a try/catch block around the line(s) of code you're concerned about.  Most of the time you'll throw it back to the caller or at least let it drop down to the end of the method, so although you do have the annoyance of having to write try/catch blocks, that is less intrusive since it is needed a minority of the time.

With returned error codes, you are hit with the annoyance of having to write error checking and handling for EVERY FUNCTION CALL, not just the few where you want to continue smoothly after an error.  And if you forget some error checking, your program may keep going and going with some crap values, corrupting data in the process.  Not only that, but you still have to worry about exceptions that may be thrown by the system or a library call. So you end up with try/catch blocks AND error checking if/else blocks.

NoName
Monday, October 13, 2003

Just today I was finding some really bad code where people were catching exceptions inside helper classes, and returning true or false, rather then catching the exceptions at the flow control point.  I was shocked.  (this is on a very high traffic, named site).  Then I check JOS and see the Exceptions article.  Wow.
    I think T. Norman's right.  Joel's site was hacked. 

Vince
Monday, October 13, 2003

Joel may be trying to hold on to his conventions, but I think he's swimming upstream.  There are just too many reasons why exceptions are better.  His argument is that each exception-throwing function is a potential execution path?  Explicit error-return-checking just makes them all explicit.  It doesn't simplify the number of paths.  Except that you'll be tempted to "reason" your way out of some of the checks to reduce the paths, and then you'll have errors that aren't checked.

The biggest difference, and the reason to use execptions: human failure with exceptions (forgetting to catch) produces visible problems.  Human failure with error returns (forgetting to check) produces invisible problems.

More on this at http://www.nedbatchelder.com/text/exceptions-vs-status.html

Ned Batchelder
Monday, October 13, 2003

So I'm not the only one that thought Joel was off his rocker today...

My experience with exceptions has been limited to using them in C# for the past couple of years, but I find them to be a huge improvement over the horrible error handling in VB.

Like any tool, exceptions can be over used. They are designed to handle, well, exceptional events.
If I have a routine that opens a file, my routine would first check to see if the file existed. If it didn't, it wouldn't throw an exception. It would return an appropriate response. On the other hand, if my routine attempted to open the file and got a disk IO error, I would throw an exception.

I find that most kinds of absolute edicts such as "Exceptions are bad. Don't use them" generally show a lack of understanding by the person making the statement.

Remember..Exceptions don't kill programs. Programmers kill programs.

Mark Hoffman
Monday, October 13, 2003

I agree with Joel, although that obviously puts me in the minority.  It may be the kind of code I write, or I may just be a dinosaur, since I mostly write C within C++ anyway, but I don't like the assumption that exceptions are not part of the fundamental code.  I think that is more likely the cause of problems with Microsoft's code than their exception handling, per se.  Hide the exception logic and you tend to propogate that myth that too many developers live with that exceptions don't happen.  Besides this, many exceptions aren't, meaning that many errors in code do not raise an exception at all, and if the nice, clean code has no error checking, you tend to assume that exceptions are what will happen.  All too often, what happens is not-exception raising mistakes, and the code needs to handle those in place, or raise an exception itself, which then removes the logic for "clean" separate exception handling.

Ben Langhinrichs
Monday, October 13, 2003

Without exceptions how do you report errors from constructors and operators, functors, etc? Oh, you use two-phase construction and ignore operator/functor errors? Nice.

If you care about error handling in C++, you have to use exceptions.


Tuesday, October 14, 2003

"If you care about error handling in C++, you have to use exceptions."

:)  no, you dont.

honestly, that kind of statement is less constructive than the "anyone who programs in VB sucks" kind.

Im another who uses exceptions as little as possible...Ive always assumed it was a lack on my part, that I just didn't 'get' it, but Im less sure of that now.

Joel has covered most of my problems with exceptions quite nicely, although he has left out a couple of things I still dont understand.

I am very interested in the counter arguments of course, this is  a subject that interests me.
<g> but your statement was not a counter-argument, it was (a) just plain wrong and (b) about as helpful as being mugged by a school teacher.

So...Im very interested in seeing some specific examples of code that illustrates 'good' use of exceptions :)

FullNameRequired
Tuesday, October 14, 2003

Someone hacked Joel's calendar and he thought it was time for his yearly April Fool's post.

Jason Watts
Tuesday, October 14, 2003

Use of exceptions can indeed be part of a poor approach to programming. I've seen recent graduates use exception handling as a substitute for analysing and fixing serious underlying problems. What's more, they thought their approach was sophisticated.

Also, it's not necessarily true that handling return codes is cumbersome. It all gets back to how good a designer someone is.

JM
Tuesday, October 14, 2003

I'm in very rare disagreement with Mr. Spolsky on this.

The best "rationale for exceptions" I've read recently, from Brad Adams (with help from Jason Clark):

http://blogs.gotdotnet.com/BradA/permalink.aspx/c9c61dbf-62a9-474f-a5fe-c171cdedb4f6

Here are the bullets:

* Exceptions Promote API Consistency
* Exceptions are Compatible with Object Oriented Features
* With Exceptions, Error Handling Code Need not be Near Failing Code
* With Exceptions, Error Handling Code is More Localized
* Exceptions Are Not Easily Ignored
* Exceptions Allow for Unhandled Exception Handlers
* Exceptions Provide Robust Error Info for Logging
* Exceptions Promote Instrumentation
* Exceptions Unify the Error Model (Hard and Logical Errors)

Eric W. Bachtal
Tuesday, October 14, 2003

Concise code (not obfuscated) can be more easily read, hence more easily understood and thus more easily made correct.  Littering the code with checks for return values goes directly against this principle.

By separating the unusual (error case) from the normal operation of the code we can understand more easily what is supposed to happen, which can aid our understanding when there is a problem.

On the other hand, exceptions can be badly misused.  They should not be an alternate form of flow control, they should be reserved for ERRORS only.

David B. Wildgoose
Tuesday, October 14, 2003

I once was flamed for mentioning using multiple return values for error handling.  Go on Joel!

Python has multiple return vals too.  The language of the id. 

Java exceptions are sometimes like, "OHMYGOD there's an ERROR!!  Drop everything NOW!!"  Multiple return vals are more like, "Here's your integer, but note I had to truncate it so here's some additional info.."

Tayssir John Gabbour
Tuesday, October 14, 2003

Not explicitly mentioned in this thread so far (but mentioned a couple of days ago): RAII.

Resource Acquisition is Initialization.

Basically, in C++:

class Locker {
    MyOSSemaphore sem;
    Locker(MyOSSemaphore sem): sem(sem()) { lockSem(sem); }
    ~Locker() { unlockSem(sem); }
};


void someMethod() {
    Locker lock(SomeCriticalSemaphore);

    ...
}

Come hell or high water, the lock will be cleanly unlocked when someMethod() exits.  Including by exceptions.

With manual error handling it would be too easy to forget to unlock the semaphore down some code path and leave the system hanging.

David Jones
Tuesday, October 14, 2003

Well I for one won't be buying anymore Fog Creek software.

You shouldn't so poorly display your IP it takes to make your products. This is like Ford's CEO saying that he doesn't believe in air bags, seat belts work just fine. I'll run right out and buy that Chevy.

Consumer
Tuesday, October 14, 2003

Mostly this horse has been beaten to death, but there's one bit of exposed flesh that doesn't seem to have been tenderized yet.  Joel claims that exceptions make it too easy for control to pass through an intermediate function, leaving its state inconsistent.  There's a really drop-dead simple solution to this:

(1) Assume *any* code you call might throw an exception.

(2) Put any necessary cleanup code inside a "finally" block.  That's what they're for.  People anticipated this problem.

Point 1 is part of why I think complex constructors and overloading in C++ are evil.  They obfuscate calls to other functions that might change state and/or raise exceptions.  Now you have to look not only at function calls but at declarations and even operator usage, so you're pretty much going to put try-blocks around *everything* even when it is in fact unnecessary.  Yech.

Point 2 can lead to a pretty deep nesting of try/finally, which is kind of ugly.  This can be addressed easily in most cases by maintaining explicit state saying what must be cleaned up when you reach the (one) "finally" clause.

Jeff Darcy
Tuesday, October 14, 2003

David says "By separating the unusual (error case) from the normal operation of the code we can understand more easily what is supposed to happen, which can aid our understanding when there is a problem."

Assuming that errors are NOT part of the normal operation of the code causes many problems.  Errors are part of the normal operation.  They may not be part of what you "mean the code to do", but they are no less part of what "the code does", and similarly, they may not be part of what you "mean the user to do", but they are no less part of what "the user does".  At least, that is my experience.

Ben Langhinrichs
Tuesday, October 14, 2003

Gee. Exceptions are called exceptions because they occur only under exceptional circumstances. Just because so many fools peruse exceptions to bubble up return values it's not appropriate to bash the whole concept.

Johnny Bravo
Tuesday, October 14, 2003

Unlike syntactic overloading, unlike enumeration types, unlike other things, exceptions have their place in OO development, in the way described by Bertrand Meyer at "Object Oriented Software Construction, 2nd Edition". My main point here is that exceptions and exception safety only make sense for me if I use the more powerful concept of Design by Contract.

In code produced without taking into account preconditions, postconditions and invariants, I'm afraid of what an exception can be user for. Validating user input or dividing by zero come to mind. There misuses of exceptions are easy to avoid if you follow the right approach to design.

From my limited experience the quantity of exceptions explicitly thrown from the code you produce will be really small.

As an aside: I find std::bad_alloc in C++ to be a good example of an exception. I'll do the same thing in *all* my code if I run out of memory: tell the user bad luck, there's no more memory, do you want to close some stuff and retry? This may not be true for all applications but it is certainly true for mine.

But even then I found Miro Samek's article in CUJ "Bug or Exception?" very interesting, in saying that even this situation should be treated as a bug in embedded systems in which you simply cannot afford to tell the user the memory is exhausting and he should stop the Lord of the Rings playing in his laptop and then retry the operation; because there's no laptop, no lord of the rings, no user in the sense of computer user, and hence no messages to the user.

Exceptions are here to stay until someone comes up with a superior paradigm. Just make sure you have the proper background to deal with them.

And yes, yes, this has been said before :)

Daniel
Tuesday, October 14, 2003

Ben says: Assuming that errors are NOT part of the normal operation of the code causes many problems.

I didn't suggest that errors didn't happen, only that they are the "exception" rather than the norm.

Some people have made comments about using exceptions to validate user input.  That is an abuse to my mind, invalid data entry is perfectly normal when dealing with fallible human beings.

Exceptions should be reserved for things that are not expected to happen.

David B. Wildgoose
Tuesday, October 14, 2003

Jeff wrote above:

>1) Assume *any* code you call might throw an >exception.
>
>(2) Put any necessary cleanup code inside a "finally" >block.  That's what they're for.  People anticipated >this problem.
>
>Point 1 is part of why I think complex constructors >and overloading in C++ are evil.  They obfuscate calls >to other functions that might change state and/or >raise exceptions.  Now you have to look not only at >function calls but at declarations and even operator >usage, so you're pretty much going to put try-blocks >around *everything* even when it is in fact >unnecessary.  Yech.

This is untrue if you use RAII properly, it is all implicitly handled by the language, and you rarely ever need try/catch blocks.

>Point 2 can lead to a pretty deep nesting of >try/finally, which is kind of ugly.  This can be >addressed easily in most cases by maintaining explicit >state saying what must be cleaned up when you >reach the (one) "finally" clause.

Of course this is true, and is the reason why the C++ model is superior, because all this machinery can be wrapped up automatically by the language without needing any try/finally clauses.

Hillel Y. Sims
Tuesday, October 14, 2003

We often talk about exception handling as if all types of programming are the same.  Office automation macros with VBA (my current project) have to allow for an almost infinite number of possible user actions.  And since it is very difficult to predict everything that a user might do, it becomes necessary to provide a catch-all structure to handle the errors that you simply didn't predict well enough to code for.

By contrast, someone that is validating user input and then passing the input on to another object that can reliably provide a return code may take a different approach.

Ran Whittle
Tuesday, October 14, 2003

Hillel, your model only works if you replace try-block nesting with function nesting.  Having to pass through ten six-line functions before you get to the one that really does the work, just so each one can take advantage of the implicit "finally" behavior as the stack is unwound and each object goes out of scope, is both inefficient and unreadable.

And it's not a C++ issue.  Stop being such a partisan.

Jeff Darcy
Tuesday, October 14, 2003

Joel exaggerates but he's hit on a valid complaint.  It's certainly true that it's not possible to tell by looking at a method call whether it throws an exception.  Something should be done about this.  An IDE could somehow present such method calls differently, such as by highlighting them in red.  Alternately this could be done at the language level by  flagging such calls with special syntax, which would allow static checking at the expense of a bit more typing.

I'm in  favor of  letting the compiler and IDE figure it out.  Even if exceptions are unchecked, it should be possible to point at any method call and get a list of all the exceptions it can throw.  (For code you don't have the source to, the compiler needs to add this information to the library, along with a list of possible callbacks so this can be traced globally.)

Brian Slesinsky
Wednesday, October 15, 2003

The idea of statically marking what exceptions can be thrown is attractive, but unfortunately impossible in a component-based system.

The problem is that you have a system like this:

    Caller -> Component A -> Component B

Call calls A. A calls B. At the time A was written, the author knew every possible exception B could throw, so A has the correct exception information. All well and good, right?

Now roll out a new version of B, that adds some exceptions. Or move B to another machine! Suddenly you've got the possibility of remoting exceptions thrown by code you never knew was there.

This problem is why checked exceptions in Java are such a pain.

Chris Tavares
Wednesday, October 15, 2003

Jeff,

I agree it's not a C++ issue, but I don't think Hillel is being partisan.  I believe his point is that a language that supports the Resource-Acquisition-Is-Initialization paradigm makes exceptions far superior to error code (or even Java-style try-finally blocks) because you don't have to write rollback or "cleanup" code.  It's handled by the destructor, which in a sense is always in its own implicit "finally" block.  Furthermore, you don't have to nest functions to get this benefit, since if you construct an object inside a for loop, it is destroyed once execution leaves that for loop--not at the end of the function.

Of course, one superior advantage Java has that C++ doesn't is checked exceptions.  Without that, C++ leaves you in the dark as to what problems could happen.  I'd like to see a language that blended both deterministic destructors as well as checked exceptions.

Douglas Clayton
Friday, October 17, 2003

There are a number of posts in this thread arguing from the existence of hideous coding styles not employing exceptions.  This is what I consider the anti-courageous position: advocate a technique because it limits the damage (usually over a political calculas of all things some programmer x might do) rather than because it's right on its own merits. 

Exceptions on their own terms are seriously problematic:

http://www.artima.com/intv/handcuffs.htm

When you take into account generic programming styles, a complementary axis of code reuse, you can quite easily find yourself in a situation where the cure is worse than the disease. 

In my shop we practice the "guarded" programming idiom: no statement is executed unless the guards on its validity have been tested.  This has nothing to do with checking error codes.  It is concerned with checking that a resource is in a valid state to support the next operation required.  A program which never executes a statement under an invalid pretext can't get itself into very much trouble. 

There is no excuse for advocating exceptions as a substitute for correctly coded guards. 

In my experience, the only valid excuse for employing exceptions is that you have a good use for the exception once it arrives at the handler.

The second theme I find in this thread is that exceptions constitute an enhanced debugging facility.  In our codebase, we compensate for our "forward march" mindset by tracking statistics of operation counts at heavily trafficed junctures within the system.  We tend to find that if the code returns to the control loop having fallen through the majority of its obligations (due to a cascade of invalid preconditions), we can immediately identify the probable cause by inspecting operation counts. 

I prefer solid code without exceptions over solid code with exceptions.  I find that the people most in favour of exceptions are those who must depend upon code libraries written to lower standards than their own code.  That positions exceptions as a firewall against mediocrity, which is not the direction I wish to see the programming industry take. 

Allan Stokes
Friday, June 18, 2004

With modern C++ and Java, exceptions are a fact of life.  For example,  new throws.  That means regardless of someone's stance on Exceptions programmers need to write exception-safe code.

Exceptions are not the problem, exception safety is.  And exception safety comes from other good oo programming such as keeping coupling to a minimum, using class factories, RAII, avoiding state changes until the last etc.

Explicitly guarding all method calls is error prone and intensive.  It bloats and slows down code and does not equal quality.  It hinders readability and maintenance. Done properly, exceptions are intuitive and natural and will improve speed.

Exceptions are not necessarily just ERRORs but they should NEVER be used for flow-control.  Exceptions should be used for "exceptional" behaviour - period.  "File not found" or "Sharing violation" are not necessarily errors but are good candidates for throwing an exception since they are exceptional behavior.

Well written code, will not be littered with try...catch blocks.  If your code is exception-safe you won't care if an exception comes bubbling through.  Use try...Catch when it is appropriate to deal with exceptional behavior.

When exception-safety is part of your programming style or "culture" rather than something that is forced, it just feels "right" to use exceptions.

John Gardner
Wednesday, July 07, 2004

*  Recent Topics

*  Fog Creek Home