The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

C++ Exception handeling

Over the weekend I had some free time on my hands so I grab and started reading 'the design and eveoution of C++'. One of the chapters that suprised me was Exception handeling. Stroustrup commeted that the original goals of exception handeling was to standerdise error handeling within code and library file provoiders.

My main concern, is that I'm starting to find conflicting arguments where and when to use exception handeling within the code itself. From a design standpoint, Microsoft enginners suggest that exceptions should be exceptional. Where in more modern interpted languages such as Java and effiel they have there own interpretation of how exceptions should be used within the context of the language.

I do work within game design, and one thing that did strike me when reading game programing is the usage of absolutly no exception handeling in any of the files or modules because of speed and space overhead.

So how do you use exception handeling if at all within your code? or do you leave them out and use error codes?
entity Send private email
Sunday, April 22, 2007
 
 
If the primary design constraint of your project is speed, then maybe Exceptions aren't the best way to do error handling.

However, for 99% of the world, error codes are a mistake waiting to happen.  With exceptions, if you screw up and forget about them, the application crashes and the debugger tells you exactly why it happened.  With return codes, if you screw up and miss one, something somewhere will not work properly.  It can be very hard to track down the source of these problems.

Besides, I like to make my functions return something useful instead of an error code.
JSmith Send private email
Sunday, April 22, 2007
 
 
I fully commit to using exceptions in my code.  I do not use status codes at all.  Old C standard calls get wrappers that use exceptions.

Each function has a contract, for the range of the input, the state of the object being acted upon, the state of the object after the method completes, and the range of the result.

I throw an exception if any of those are not met.  Thus, any call is expected to complete successfully.  If it does not, I am able to handle it.

In my API, I like to make sure that it is not nessecary to catch exceptions to do anything.  (For example, if you have a find(x) which throws if x is not in the set, you also need a isMember(x) that allows you to write code avoiding the error).

Sunday, April 22, 2007
 
 
Error codes? That's so C. In C++, I return objects.
dev1
Sunday, April 22, 2007
 
 
If your talking about having a contract between the spupplier and the user then i fully agree. That you state the pre-conditions,postconditions of the routine. If either of the cases are not meet, then the contract is void and you abort the application to fix the bug.

Although, I'm of the viewpoint that a precondition should not throw an exception because it allows the routine to return like it has completed its jobs. Because of the try catch block. It allows the bug in the software not to be identified and fixed.

The only time i can see using exception is when it becomes part of the well defined behaviour of the routine.
entity Send private email
Sunday, April 22, 2007
 
 
If the routine completes, you recieve a value.
If the routine has an error of anytime such that a specific value cannot be return, then an error should be thrown.

Try blocks should generally not be wrapped arround a single call.  Only catch exceptions that you are going to rectify.

Sunday, April 22, 2007
 
 
Hi

I'm assuming the OP does not have English as a first language, so a few tips:

 "Exception handling"
 "evolution"
 "engineers"
 "standardise"
 "Eiffel" (language)
 "commented"
 "I had some free time on my hands so I grabbed..."
DJ Clayworth
Monday, April 23, 2007
 
 
In general, I try to avoid "handling" exceptions.  In most cases, if it can be handled, it could have been prevented and truly unwinding state to a known good point is often much more difficult than people realize.

Prevent bad state from occurring and then the only handling needed is the appropriate display, logging, or forwarded for the system.
Wayne M.
Monday, April 23, 2007
 
 
The speed thing is a non-issue.  Using exceptions makes your code easier to read and less brittle, which means you can more easily modify it to use different algorithms when you identify performance issues.  Algorithm choice is usually the major performance issue in my experience.  If exceptions become a significant performance issue, they'll likely become so in a very specific area (identifiable with a profiler) that can be refactored to use error codes.  This will almost always be significantly less than 1% of your code.  Why screw up the other 99% to avoid having to tweak that 1% later?

Error code style:

  int intermediate;
  if (HasOutParam(&intermediate) != SUCCESS)
    return FAILURE;
  int final;
  if (TakesParam(intermediate, &final) != SUCCESS)
    return FAILURE;

Exception style:

  int final = TakesParam(HasReturnValue());

I don't know about you, but I would have an easier time perfecting the algorithmic performance of the exception style code.

I'm also fully in agreement that normal execution should not usually generate an exception, so isMember(x) is definately a requirement when you have find(x).  This is from, again, a readability/maintainability perspective rather than a performance perspective.
Nick Barratt
Monday, April 23, 2007
 
 
If exceptions are for situatons when the program cannot run properly at all (e.g. when its connection to an essential database is unavailable), in those situations it may not matter how fast it is.
Christopher Wells Send private email
Monday, April 23, 2007
 
 
> I don't know about you, but I would have an easier
> time perfecting the algorithmic performance of the
> exception style code.

Using your example, it would be easy enough to re-designing the code to work as follows:

  int final;
  TakesParam(HasOutParam(&final), &final);
  return final;

You could even go one better and make it work like this:

  return TakesParam(HasOutParam());
Jussi Jumppanen
Monday, April 23, 2007
 
 
Sorry, HasOutParam can fail.  You need to check for this condition.

Tuesday, April 24, 2007
 
 
>  int final;
>  TakesParam(HasOutParam(&final), &final);
>  return final;

is not at all equivalent code.  You're passing the result code from HasOutParam rather than the out-variable returned value.  And both TakesParam and HasOutParam can return error codes; dealing with the associated errors is the point of this discussion.
Nick Barratt
Tuesday, April 24, 2007
 
 
What I find odd is the people who insist that exception handling support makes executables larger and slower, yet somehow assume that adding code like this is "free": if( result != ok ) { callErrorhandler(); doCleanup(); return anotherErrorCode; }

Wednesday, April 25, 2007
 
 
some coward wrote:

  "What I find odd is the people who insist that
    exception handling support makes executables
    larger and slower, yet somehow assume that
    adding code like this is "free":
   
      if( result != ok ) {
          callErrorhandler();
          doCleanup();
          return anotherErrorCode;
      }"

First, the code you site is, as far as execution speed goes, nearly free, so long as you are running it on a reasonably modern machine. Any reasonable branch predictor should assume that the branch associated with the if-statement is untaken, so you will only incur a speed hit when you have to handle an error. Under regular operating conditions, the if will be no more than 1 lost cycle (and, on most modern machines, the branch will be a 0 cycle delay).

Second, my impression has always been that the problem with exception handling is the overhead associated with stack unwinding and any bookkeeping required to go along with it. I'm not expert in the implementation of C++ runtimes, so I won't speculate further on this, but that has been the impression I have gotten from reading other's opinions (who, I assume, know something about what they are talking about).

Code bloat, on the other hand, is likely to be worse for the explicit error code testing. I would be very surprised if the stack unwinding code in C++ weren't sequestered into a single routine in the C++ runtime, and my impression is that, well written exception handling code only catches after a long string of code, not after every statement that might fail.
Jeff Dutky Send private email
Wednesday, April 25, 2007
 
 
"Second, my impression has always been that the problem with exception handling is the overhead associated with stack unwinding and any bookkeeping required to go along with it."

Are there any practical examples out there where the exception handling was identified as the performance bottleneck? By profiling and measurement, not by guessing, of course.
Secure
Thursday, April 26, 2007
 
 
The folks who write games are notorious for trying to eke out every last microsecond.

http://gamearchitect.net/Articles/ExceptionsAndErrorCodes.html
Mark Ransom Send private email
Thursday, April 26, 2007
 
 
The numbers in the article are significant, not to use exception handeling.
entity Send private email
Thursday, April 26, 2007
 
 
Did a ruth estimate, if you wanting to achieve 32 fps in your new game, with exception handeling you will be wasting about 13fps, so your target will have to justify having 45fps to take into account the penality.

This isnt a problem for desktop applicaiton development, such the number of bussiness that use virtual machines these days. The requirement for speed just isn't there.
entity Send private email
Thursday, April 26, 2007
 
 
> Sorry, HasOutParam can fail.  You need to check
> for this condition.

No kidding:

  int  TakesParam(int TheHasOutParamResult)  {
    int result = TheHasOutParamResult;

    if (result == SUCCESS) {
        if (Doing some meaningless stuff worked)
            result = SUCCESS
        else
            result = FAILURE
    }
    return result;
  }

  int final = TakesParam(HasReturnValue());

Now I am not saying you should structure the code this way, but rather showing it can be written this way to achieve the same ‘one line of code’ result as the so called ‘superior’ exception handling.

IMHO this code, just like the original, is very poorly structured and posting poorly structured code as some kind of proof that exception handling is somehow better than error handling is just rubbish.
Jussi Jumppanen
Thursday, April 26, 2007
 
 
FWIW I am not exactly sure what your example is trying to do, but in terms of code structure this is how I would have coded it.

  int intermediate;
  int result = HasOutParam(&intermediate);

  if (result  == SUCCESS) {
    int final;
    result = TakesParam(intermediate, &final);
  }
  return result;
Jussi Jumppanen
Thursday, April 26, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz