TweetFollow Us on Twitter

C++ Exceptions
Volume Number:11
Issue Number:10
Column Tag:C++ Workshop

Try C++ Exception Handling

How to make use of the C++ exception standard in your C++ code

By Kent Sandvik

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

Exception handling is a feature of the ANSI C++ specification first formally proposed back in 1990, but only recently adopted by compilers on the Macintosh. This has changed with compiler level support for exceptions in CodeWarrior 6, and the promise that Symantec will provide this feature in their C++ compiler soon.

For developers used to working with class libraries, exception handling is nothing new. MacApp, TCL, PowerPlant all have provided macros to implement this feature with setjump/longjmp calls. However, there are still a number of manual steps for the programmer because this technique can interact with compiler optimizations. Supporting exceptions directly in the compiler, which has the ability to make sure that variables and stack information, including C++ objects, are valid between exception cases means that the framework and developers don’t need to worry about these runtime issues. In addition, this means that C++ code is more portable across computer environments.

Most of the C++ literature dealing with exception handling tends to be academic and doesn’t show how C++ exception handling is used in real life. This article will get you started if you want to add standard C++ exception handling into your current project. I will describe what exception handling is, how it works and how to implement exception handling using the proposed ANSI C++ syntax. We will also discuss some pitfalls and design issues.

Error Handling and Exceptions

The generalized model for exception handling is to have, within a part of a program, separate execution paths for normal execution and error recovery. When an error (exception) is detected, the program can ‘throw’ it to the error recovery code (exception handler). The recovery code may then attempt to recover from the error and resume normal program execution, or do some clean up and pass control to the next handler. As noted above, errors are called exceptions, and the error recovery code is called an exception handler.

It is important to note that exception handling is just one of many ways to deal with error cases. The following are some other error reporting techniques used by software engineers:

• Return an error status from the function (OSErr)

• Global error variable (errno in UNIX environments, QDErr and similar low mem globals on the Mac side, fortunately we have functions to return these errors nowadays)

• Invocation of a special, user-defined error function, or callback function

• Jump to a previous point on the stack via setjmp/longjmp

• Use of assertions to test a state, signal if assertion failed

Some examples of error situations are: truly fatal errors, assertions (we assume that something is OK, and it is not), algorithmic failures (like the dreadful one-off with array elements), and alternate return signals (end of file markers arriving with a file stream for instance). As you can see, these are not all fatal errors or errors at all, but they are exceptional cases which can be handled using exception handling.

The beauty of exception handling lies in not only how it relieves the programmer from handling the exceptional situations explicitly, but also allows increased flexibility in dealing with exceptions. For instance, low-level library code needs to signal information about an exceptional condition to the user interface through intervening library code. Let’s say that a network connection is needed and certain C++ objects need to be created to manage it. One part of the code will try to create the objects. If the object creation leads to an unexpected state (suddenly can’t make the connection), the network object could throw an exception back to the code that tries to use it, and at the same time unwind any partially or fully created objects and other variables on the stack.

Should exception handling should be used to handle all these cases, or should it be used selectively?

Several facts speak in favor of using it liberally. The code is cleaner if the error handling is factored out from the normal flow of execution. Error handling code is reused more often, and the actual function blocks would spend less time dealing with error situations across the board, because the task is delegated to specifically designed exception catch blocks that deal uniformly with error situations. Such catch blocks could provide a uniform way of informing end users about error conditions.

On the other hand, because some runtime environments impose a higher runtime overhead on exception processing than normal execution, exception handling should not be used casually as a way to signal information from one part of the call chain to another, or as a quick and dirty way to implement message passing inside an application.

[Some programmers may disagree with this latter assertion. For instance, it is often useful to use an exception as a means of loop termination when it is easier to detect the termination condition and recover than it is to predict it - such as throwing an EOF exception when trying to read past the end of a file. This has the same effect as a break, but can be done several levels deep in the call chain (as you can with longjmp, but more intuitively). In general, I tend to use a 10:1 rule when using an exception within the normal - if the normal case is executed at least 10 times for each time an exception is thrown then an exception is okay. - sgs]

Why Compiler Support for Exceptions is Better

MacApp, TCL and similar frameworks have implemented specific macros and data structures that provide a way to signal exceptions, provide information about the exception, and indicate that a handler that will catch the exception. In most cases these techniques are built around the ANSI C setjmp and longjmp functions. setjmp saves the current program environment inside a jmp_buf data structure. longjmp will let you jump back to the point saved with setjmp. Think of it as a very smart goto that keeps track of the environment setting.

Macro implementations of exceptions work fine, generally, but there are some known problems. Smart compilers like to optimize variables, stuff them into registers or eliminate them. If this happens, the longjmp back to the earlier point might lead to a situation where things are not the same after all. The solution is to declare variable volatile. This is a way to tell the compiler to keep its hands off the variable. Unfortunately, not all compilers have a working volatile keyword. What MacApp had to do in this case was to create a VOLATILE macro. All this macro does is take the address of the variable, which ensures that the compiler (Cfront in this case) will not place this variable into a register. Modern compilers are still pretty keen on optimizing away variables if they have a chance; hopefully such compilers have a working volatile keyword.

Another issue concerns threads and maintaining a linked list of exception handlers. In many cases we want to have a list of exceptions that are valid (for instance the FailInfo implementation of MacApp). If the application spins off threads, and one of these threads throw an exception, there’s a chance we want to roll back to an earlier state. In such cases we want to yank out the exception structure from the linked list. Now, if we don’t keep track of this case with the thread system (for instance, by creating our own thread dispatcher that will know of such data structures and keep the linked list intact), we might yank out the exception frame from the middle of the list and suddenly the linked list is no longer linked.

Also, if we want to roll back to a known state, and this means that there are objects created that should be destructed, it is really up to the programmer to know about this situation.

This is where a compiler level implementation of exception handling is better. Compilers know about what variables should be kept volatile, what data structures are allocated and when these should be destructed and so on. Dealing with threads case is still a tricky one, though. This is a good example where the platform architecture and the language syntax/semantics are not harmonized. C++ does not go far enough to take care of issues related to threads, and it is the the programmer’s responsibility to be alert about this and similar cases.

C++ exception handling ensures that all class instances will be properly de-allocated off the runtime stack or from the heap. This means that we can now take actions in constructors that can fail because it is possible to return an error result by throwing an exception. If a constructor fails, the de-allocation code is called by the compiler, so that we don’t need to worry about memory leaks and non-allocated objects on the stack. For instance, a constructor could try to create files, and if it fails, the destructor will remove them. In other words, constructors are now far more productive.

Needless to say, C++ exception handling requires runtime support. For normal functions the compiler knows where in a program a function is called, and knows where to pick up execution when the function returns. For exception handling the compiler does not know for a particular throw expression what function the catch block resides in, and where execution will resume from after the exception has been handled. These decisions won’t happen until runtime, so the compiler will leave information around for the proper decisions to take place (generates data structures to hold this information needed during runtime). This means additional overhead in the application execution time, stack size and so on.

Exception Basics, Try and Catch

Someone somewhere will signal that they have an exceptional situation. When an exception occurs, an exception handler is triggered on a higher level, and depending on the situation the handler may do any number of things. It is up to the programmer to indicate where exceptions may occur and should be handled. In the following code, the errors are handled in the block marked with the keyword “try”:

    // I’m in trouble
 throw exception;

 try {
    DoSomething();  // This will throw an exception, and the catch
    // below will catch it.

 catch (exception)
    // Ooops, what to do?

So what should we do inside the catch block? We might change something and retry the action, return normally (as nothing really happened), rethrow the same exception with modifications and assume that a higher level catch block will help out, throw a different exception, continue execution to the next statement, or just terminate the program.

When we design applications it is important to define what each layer of the application (from the low level utility functions all the way to the end user level) should do with an exception when exceptions are triggered. Various libraries, such as the new ANSI C++ standard library, include exceptions thrown from various class member functions. It is important that the application will catch any relevant exceptions thrown - assuming that the exceptions are documented, of course. We’ll discuss design issues in more detail later.

C++ Exception Coding, Exception Classes

Here’s a more complex example. We implement exceptions that will throw objects instantiated from classes we’ve defined. Let’s investigate each case one at a time:

 aFoo = new Foo;
 aFoo->DoASillyThing(); //This will throw an exception

Here we will do an initialization of a Foo class, and then call a member function that will trigger an unexpected situation (that was hard coded). The try block will tell the compiler that it should catch any exceptions happening from this exercise.

 catch (...) // catch everything
 cerr <<"We catch every single exception here" << endl;

This is the catch block that is usually programmed after the try case. In this first example we will try to catch every possible exception that is bubbling up from the try case (note the ... notation).

However, in most cases it makes sense to specialize on the exceptions that we want to catch. An exception handler can be written to catch only exceptions of a certain class, or a sub-class. (The classes used in our example are described in the next section.) We write:

 catch (TSeriousMacException &ex) // catch only TSeriousMacException
 cerr << "SERIOUS EXCEPTION: " << ex.GetExceptionMessage() <<  
 ",  OSErr: " << ex.GetExceptionOSErr() <<
 ", File: " << ex.GetExceptionFile() << ",  Line: " <<         
 ex.GetExceptionLine() << endl;

    // Use real Mac UI to signal about the seriousness to the user of the application.
 catch(TMacException &ex) // catch TMacException
 cerr << "EXCEPTION: " << ex.GetExceptionMessage() << ",       
 OSErr: " << ex.GetExceptionOSErr() <<
 ", File: " << ex.GetExceptionFile() << ", Line: " <<          
 ex.GetExceptionLine() << endl;

    // After the exception is handled, we will continue here (not from where the
    // exception was thrown.)

In the above examples, we catch specific exceptions. Note that these exceptions are objects. Exceptions could be strings (“Help”), integers, and various other data structures. The PowerPlant library uses a less elaborate exception structure that is simply a long. In many cases it makes sense to build an exception class hierarchy (more about this later).

Exceptions are caught in a predefined order, top down, from the specific (sub-class) to the generic. This ordering is important. If you catch a parent class exception before the child one, the child exception is never handled. In this case the TSeriousMacException is handled first, even if it’s inherited from the TMacException class. Note also that we will terminate the application with ExitToShell when the TSeriousMacException is caught, otherwise we will continue if the TMacException is handled.

Note that the execution of the code, after the exception in this particular catch block, will continue on the next code line. The execution of the program does not resume where the exception was thrown. However, the catch block could rethrow the exception to a possible next catch block, as in:

 catch(TMacException &ex)

The catch block could also modify the current exception object, or throw another exception object, then the next layer or catch frames will take over (assuming these layers exist). Note also that there will not be a recursion if the same exception object is thrown again, in other words the same exception block is not triggered again.

As shown in the example, the exception objects could contain both member functions and fields. This is handy; when we then throw the exception we could provide information back to the catch block about the situation. As we pass the exception object as a reference, we could modify the object, and pass new information along if we want to rethrow the same exception.

A Little More About Exception Classes

We have defined the exception classes to pass information about the error:

class TMacException 
 TMacException(const char *theMessage, const OSErr theError) 
 TMacException(const char *theMessage, const OSErr theError,   
 const char *theFileName, const long theLineNumber)            
 const char*   GetExceptionMessage(void)     { return fMessage;};
 const OSErrGetExceptionOSErr(void){ return fError;};
 const char*GetExceptionFile(void) { return fFileName;};
 const long GetExceptionLine(void) { return fLineNumber;};
 const OSErr   fError;
 const char*   fMessage;
 const char*   fFileName;
 const long fLineNumber;

class TSeriousMacException : public TMacException
 TSeriousMacException(const char *theMessage, 
  const OSErr theError) 
 : TMacException(theMessage, theError, "NO FILE SPECIFIED",    
 0L) {};
 TSeriousMacException(  const char *theMessage, 
 const OSErr theError, 
 const char *theFileName, 
 const long theLineNumber) 
 :  TMacException(theMessage, theError, theFileName,           
 theLineNumber) {};

The TMacException is the base class. This class has fields for storing the OSErr, a string message, file name, line number and it could also contain other various fields. We place these fields into a protected area which is why we need inlined accessor member functions (this is not a requirement, but when we do object oriented design, data encapsulation is a good thing to do anyway).

TSeriousMacException is an interesting class, as it does not really contain any additional fields or member functions. Instead, we pass the values back to the TMacException when we construct the exception class. Why? Well, this was a way to signal that this class is more serious than the normal TMacException, and when we look back at the catch block that catches from specific to more generic exceptions we now have a way to signal priority levels to the catch block.

Throwing Exceptions

So far we have shown both the try and catch blocks, but what about throwing exceptions? Here’s finally the DoASillyThing member function:

void Foo::DoASillyThing(void)
 throw TMacException("We did a silly thing", unimpErr, 
 __FILE__, __LINE__);


throw TSeriousMacException("We did a really serious, silly thing", 
 unimpErr, __FILE__, __LINE__);

What we do is to create an exception object as part of the throw action. We could also do things like:

throw “Help me!”;


throw anOSErr;

and then we assume that there’s a catch block that will indeed catch such exceptions, strings or OSErr values (or catches any exception). In this example I wanted to write a flexible exception class that contains as much information about the situation as possible, including possible OSErr values and an information string. The __FILE__ and __LINE__ macros for providing information where the exception was triggered also helps out when debugging C++ code. If typing these variables makes your fingers bleed, here’s a macro:

#define THROWEXCEPTION(name, number) \
 throw TMacException( (name), (number), __FILE__, __LINE__)
#define THROWSERIOUSEXCEPTION(name, number) \
 throw TSeriousMacException( (name), (number), __FILE__,       

PowerPlant defines similar macros as wrap-arounds for OSErr and NULL pointer tests that will throw an exception if the macro test fails.

Note that the object is constructed at the throw point. This might sometimes not look at the case, as in:

enum MyFailures { noErr, bigErr, semiBigErr};
enum myState = noErr;

 throw myState;  // we construct the exception object here, not           
    // before!

One problem with constructors and destructors in C++ is that they don’t return any values, so usually you need to implement state information fields inside the class and poll these to know what happened after a constructor or destructor was triggered. Exception handling will now help out, as you could throw exceptions from a constructor or destructor, or:

 throw TMacException("Problems inside the Bar constructor",    
 noErr, __FILE__, __LINE__);

Remember, exception handling should not be used as a way to signal state directly. Instead this is a way to signal other parts of the code that the constructor never completed fully, so the example above is not fully operational. At the same time any partial object or variable content is also purged by the compiler.

Application Design

It is important to fully define how exceptions are triggered, and what parts of the code will intercept and possibly rethrow the exceptions (using the rethrow key word from inside the catch block) to the next level. If this is not fully architected, it will be very hard to know what was going on inside the code when exceptions are triggered.

If you generate objects as part of the initialization of your application, you should try to catch any exceptions that might bubble up from the classes or any class libraries you are using. After this you still need to install catch blocks inside your WaitNextEvent loop block (in some cases the same catch blocks as mentioned earlier). Then depending on the case you might continue with your event handling (and the application), or terminate the program, and if possible provide the end user a chance to save modified data.

Here’s an example of a simple three-level design using exceptions:


By default when an exception is thrown, and no handlers exist for the thrown exception, the built-in function terminate is called. In the default behavior terminate will call abort (that terminates the program). That means that you need to include the ANSI C library that specifies abort, or then write your own fake abort, as in:

extern "C" void abort(void);

void abort(void)
    // Do whatever it takes, DebugStr or whatever...

It makes sense to override this function for more control of what is going on, especially if you are using an external C++ library that will throw both known exceptions (documented) and unknown exceptions (not documented). You could override the default terminate function by using the set_terminate function call (note the correspondence with set_new_handler), as in:

void HandleTerminate(void)
 cout << "This is the my own terminate function that I've      
 installed!" << endl;



In many cases you want to recover resources when your function is terminated due to exceptions. One practical way is to tie resource recovery to objects. Such objects could live within the scope of the function, and its destructor is called if this object still exists when the function is terminated due to an exception. Such automatic objects mean that you could do less work inside the catch block. Here’s a simplified example:

 void DoSomethingWithMemory(void)
 try {
 TMemoryBlock myHandleObject; // this might even lock the
    // handle
    // Do something that might cause an exception to happen
           // if so the TMemoryBlock object’s destructor is called,
    // memory is unlocked, released and so on.

Try to recover from exceptions only if you know you can take a reasonable action to correct the situation. End users won’t like if you catch exceptions and continue with the code, and the system crashes milliseconds later due to a low memory corruption situation, for instance. If you don’t know what really happened, it’s better to rethrow the exception upwards than try a random action that might or might not correct the situation.

You could write extended exception classes that have various options, for instance a debug version will drop you to MacsBug signalling situations, while an end user version will maybe provide an alert, or log status information into a text file.


I have provided a smaller Metrowerks project and C++ code that shows how the various exception parts work together. Feel free to comment and uncomment code lines in order to learn what is happening.

The Annotated C++ Manual (Ellis & Stroustrup) was the de facto standard concerning the exception handling syntax and semantics. The evolving ANSI C++ standard has today taken over the responsibility concerning standardization. The following URLs are handy for finding the latest drafts:

I would also recommend careful reading of the README files for the various C++ compilers; this various compilers might not implement the full standard at this point of time.

As C++ exceptions are a relatively new feature, we will need to refine how we use exceptions based on more practical experience. Also, MacApp, TCL and other frameworks/libraries have exception implemented using macros, and practicing on these platforms is valuable, and in some cases there might not be a need to rewrite exception handling code just so it conforms to ANSI C++, unless code portability and C++ standard following is a big issue.


Ellis and Stroustrup, Annotated C++ Reference Manual, Addison-Wesley.

David Reed, “Using C++ Exceptions”, C++ Report, March-April 1994.

David Reed, “Exceptions, Pragmatic Issues With a New Language Feature”, C++ Report, October 1994.

Booch and Vilot, “Designing with Exceptions”, C++ Report, July-August 1993.

Josee Lajoie, “Exception Handling: Supporting First Class Objects”, C++ Report, June 1994.

Taligent, Taligent’s Guide to Designing Programs, Addison-Wesley.

Think Reference 2.0: Example of a setjmp/longjmp implementation.


Community Search:
MacTech Search:

Software Updates via MacUpdate

Ys Chronicles II (Games)
Ys Chronicles II 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: After a hard fight to recover the six sacred books in Ys Chronicles I, Adol is back for a sequel! | Read more »
FINAL FANTASY Ⅸ 1.0.4 Device: iOS Universal Category: Games Price: $16.99, Version: 1.0.4 (iTunes) Description: ==========●Special sale price for the FINAL FANTASY IX release! ●20% off from February 10 to February 21, 2016... | Read more »
Tennis Club Story (Games)
Tennis Club Story 1.03 Device: iOS Universal Category: Games Price: $4.99, Version: 1.03 (iTunes) Description: Aim for the ace position of tennis club prestige in this simulation! Your leadership decides if players make it to the big... | Read more »
Juggernaut Wars guide - How to use skill...
Juggernaut Warsis a brand new auto-RPG on iOS and Android that challenges you to build a team of heroes, send them out into various different missions to defeat waves of heroes, and level them up to increase their power. The actual combat itself... | Read more »
Check out the new Pirate Attack update i...
Love pirates and board games? Well, you'll love the new Pirate Attack themed update that just launched in Game of Dice. It adds a bunch of new content themed around pirates, like an all new event map based on a pirate ship which revamps the toll... | Read more »
Splash Cars guide - How to paint the tow...
Splash Cars is an arcade driving game that feels like a hybrid between Dawn of the Plow and Splatoon. In it, you'll need to drive a car around to repaint areas of a town that have lost all of their color. Check out these tips to help you perform... | Read more »
The best video player on mobile
We all know the stock video player on iOS is not particularly convenient, primarily because it asks us to hook a device up to iTunes to sync video in a world that has things like Netflix. [Read more] | Read more »
Four apps to help improve your Super Bow...
Super Bowl Sunday is upon us, and whether you’re a Panthers or a Broncos fan you’re no doubt gearing up for it. [Read more] | Read more »
LooperSonic (Music)
LooperSonic 1.0 Device: iOS Universal Category: Music Price: $4.99, Version: 1.0 (iTunes) Description: LooperSonic is a multi-track audio looper and recorder that will take your loops to the next level. Use it like a loop pedal to... | Read more »
Space Grunts guide - How to survive
Space Grunts is a fast-paced roguelike from popular iOS developer, Orange Pixel. While it taps into many of the typical roguelike sensibilities, you might still find yourself caught out by a few things. We delved further to find you some helpful... | Read more »

Price Scanner via

Apple restocks Certified Refurbished Mac mini...
Apple has restocked Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz Mac mini: $419 $... Read more
What iPad Pro Still Needs To Make It Truly Pr...
I love my iPad Air 2. So much that I’m grudgingly willing to put up with its compromises and limitations as a production tool in order to take advantage of its virtues. However, since a computer for... Read more
21-inch 3.1GHz 4K on sale for $1399, $100 off...
B&H Photo has the 21″ 3.1GHz 4K iMac on sale $1399 for a limited time. Shipping is free, and B&H charges NY sales tax only. Their price is $100 off MSRP: - 21″ 3.1GHz 4K iMac (MK452LL/A): $... Read more
Apple price trackers, updated continuously
Scan our Apple Price Trackers for the latest information on sales, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. We update the trackers continuously: - 15″... Read more
Save up to $240 with Apple Certified Refurbis...
Apple is now offering Certified Refurbished 12″ Retina MacBooks for up to $240 off the cost of new models. Apple will include a standard one-year warranty with each MacBook, and shipping is free. The... Read more
Apple refurbished 13-inch Retina MacBook Pros...
Apple has Certified Refurbished 13″ Retina MacBook Pros available for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 13″ 2.7GHz... Read more
Apple refurbished Time Capsules available for...
Apple has certified refurbished Time Capsules available for $120 off MSRP. Apple’s one-year warranty is included with each Time Capsule, and shipping is free: - 2TB Time Capsule: $179, $120 off - 3TB... Read more
13-inch 2.5GHz MacBook Pro (refurbished) avai...
Apple has Certified Refurbished 13″ 2.5GHz MacBook Pros available for $829, or $270 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz MacBook Pros... Read more
Apple refurbished 15-inch Retina MacBook Pros...
Apple has Certified Refurbished 2015 15″ Retina MacBook Pros available for up to $380 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 15″ 2... Read more
New Liquid Crystal Technology Prevents Automo...
Researchers at the University of Central Florida have developed three new liquid crystal mixtures which will allow automobile displays to operate at unprecedented high and low temperatures In... Read more

Jobs Board

Lead Engineer - *Apple* OSX & Hardware...
Lead Engineer - Apple OSX & Hardware **Job ID:** 3125919 **Full/Part\-Time:** Full\-time **Regular/Temporary:** Regular **Listed:** 2016\-02\-10 **Location:** Cary, Read more
*Apple* System Analyst - ATOS IT Services...
Apple System AnalystReference no.198783CountryUSARegionUS - CALIFORNIACityUS - CALIFORNIA - BURBANKPosition TypeProfessionalJob AreaIT SupportJob TypeFull Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Subject Matter Expert - Experis (Uni...
This position is for an Apple Subject Matter Expert to assist in developing the architecture, support and services for integration of Apple devices into the domain. Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.