tags:

views:

530

answers:

6

Probably exceptions is the most controversial C++ feature. Many teams including google do not use them. Of course the decision to use them or not depends on the context -- for example, in some games it might be ok to crash on out-of-memory, but not in a medical equipment control software. Apart from out-of-memory, some teams may use exceptions for network disruption, file-not-found etc. but others may say this is too common to be called an exception (others may say, but if it is common, so what?)

Often the decision not to use exceptions is based on the potentially misguided argument that it is difficult to write exception-safe code. Some people say the argument is misguided because using the alternative of using error codes will lead to at least as much difficult code. David Abrahams clarifies this point.

In this question, I am curious to know:

  • For what cases do you use exceptions?
  • What is the context of your application? Why can't you live without exceptions?
  • How do you manage to write exception-safe code? What is the level of investment you have to make?
  • Is/Was it worth it?
+14  A: 

I use exceptions for exceptional behaviour, and not too frequently. When debugging crashes, I frequently use break-on-exception, so if your code is using exceptions to handle things that normally occur, I shall be quietly fuming at you. Use them when things have gone wrong in an unexpected way.

Acceptable example: server your code relies on is unavailable, so your service cannot do anything meaningful.

Example that means I'm annoyed at your code: user entered a number greater than 100, as input to your function which expects a number <=100.

In fact, if you're working on a user-facing application, the user probably shouldn't be able to do anything that generates an exception.

This is a very grey area though, so feel free to upvote/downvote me if you agree/disagree. If you disagree please post a comment saying why - I'm curious to hear other guidelines/rules/metrics.

Dominic Rodger
+1 for "user's actions should not result in an exception".
avakar
A: 

In my experience if I use exceptions to "smartly" recover the exception handling tends to over time become more and more complex when it finally adds way too much overhead compared to value. Instead I have adopted the approach of using exceptions purely for detection, having an exception thrown in a function and logging it at that point allows me to faster find ev. problems. Using hierarchies where you rethrow the exception to capture it in a higher level well I tried that but find it makes the code unnecessarily difficult to follow without a major benefit.

Anders K.
+7  A: 

Although a lot of people treat exceptions in C++ really as 'something exceptional happened', I find them incredibly handy to do basic error-checking / validation as well, mostly at application-level (as in not in the core of the library)

Example, I'd rather write

try
{
  MethodA();
  MethodB();
  //.. a whole lot of other methods crucial to succeed for app initialization
}
catch( const SomeException& e )
{
  //show user the critical error contained in e
  return 1;
}

then writing

if( !MethodA() )
{
  //retrieve and show error
  return 1;
}
if( !MethodB() || !MethodC() )
{
  //retrieve and show error
  return 1;
}
//etc

This tends to lead to less code, also within the methods themselves.

stijn
This leads to cleaner code, See "Clean Code" from Uncle bob
TimW
Funny how both this and the answer above it are up-voted and yet they're exact opposites.
Blindy
@Blindy: I think they're both very reasonable approaches, you just can't use them both simultaneously. Ideally, the purpose of a style guide is to specify which of several reasonable techniques will be used on a given project.
Steve Jessop
@stijn So to summarize: you use exceptions where performance is not an issue, to write cleaner code.
Amit Kumar
In the exception case, you're showing the same error message regardless of the problem. In the non-exception code, you're showing a more specific error. You can make the exception code show more specific errors by adding and catching more exception types. By then, though, you've written the same amount of code. I'm pro-exception, but this example doesn't really make the case.
Adrian McCarthy
Exceptions shouldn't be used for code logic. It should be used to catch Exceptions... ie, unpredictable behavior. Exceptions are slow
Joe Philllips
@Amit yes that's pretty much it, although I have to stress that I only use them as in the example in the top-level of the application. For the core, I use them only for exceptional behavior like out of memory and such.@Adrian: not excactly; in the exception case, the exception simply contains the same error message as in the non-exception case, and that message describes clearly what the error is, most of the time I put some kind of source ID in there as well.
stijn
I sort of agree with this post. Depends on the platform. Im developing for Win CE on a ARM. Exceptions take account 25% of execution timetime, regardless of exceptions are thrown. So a simple throw <something> will do harm. Blergh
PoweRoy
+2  A: 

I'm generally pro-exception for truly exceptional situations, but I probably have a higher bar than most in deciding what's "exceptional".

What makes this hard is that the low-level code must decide what's exceptional, but only the high-level code knows whether a given error is exceptional. For example, consider a function that loads an icon. What should it do when it fails? Only the calling code knows whether the failure is critical (the program NEEDS that icon to proceed) or not (the icon is just decorative).

Practical issues tend to trump elegance. Constructors that fail have to throw exceptions in order for RAII to work. On the other hand, destructors shouldn't throw exceptions. Then there are all the barriers across which you cannot let an exception fly. For example, in Windows, it's not safe to let an exception propagate out of an OS callback (like a window procedure). If you're multi-threaded, an unhandled exception in one of your worker threads will bring down the process, without unwinding and calling the d'tors on your other threads. Device drivers and kernel code generally cannot use C++-style exceptions because of paging constraints. COM doesn't play nice with exceptions.

Adrian McCarthy
+1 new insights in your answer.
Amit Kumar
A: 

Last time I used them:

throw "Constant (appropriate) error message"

when encountering a serious condition.

A couple of times I stuck extra data in global variables, but that was before I wrote multi-threaded code. I'd have to rethink that one (obviously).

Not that I'd recommend this technique anymore.

Joshua
"I'd recommend this anymore": Did you mean "I wouldn't recommend" or "I'd recommend ... more"?
xtofl
@xtofl, I think you failed reading comprehension. The sentence essentially means I no longer recommend this.
Joshua
+1  A: 

Almost everybody writes code can throw exceptions. They're all over the standard libraries. Given that, I don't think a "no exception" policy is a good one.

I don't write my own exception-throwing code much, because I don't directly deal with that many things that are likely to go wrong such that throwing would be useful. If something goes seriously wrong where there's no obvious way to fix it, throwing is a good idea.

I do try to make sure that what I write will work sanely in case of exceptions being thrown.

David Thornley