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

World of Tanks Generals guide - Tips and...
World of Tanks Generals is a brand new card game by the developer behind the World of Tanks shooter franchise. It plays like a cross between chess and your typical card game. You have to keep in consideration where you place your tanks on the board... | Read more »
TruckSimulation 16 guide: How to succeed...
Remember those strangely enjoyable truck missions in Grand Theft Auto V whereit was a disturbing amount of fun to deliver cargo? TruckSimulation 16 is reminiscent of that, and has you play the role of a truck driver who has to deliver various... | Read more »
The best GIF making apps
Animated GIFs have exploded in popularity recently which is likely thanks to a combination of Tumblr, our shorter attention spans, and the simple fact they’re a lot of fun. [Read more] | Read more »
The best remote desktop apps for iOS
We've been sifting through the App Store to find the best ways to do computer tasks on a tablet. That gave us a thought - what if we could just do computer tasks from our tablets? Here's a list of the best remote desktop apps to help you use your... | Read more »
Warhammer 40,000: Freeblade guide - How...
Warhammer 40,000: Freebladejust launched in the App Store and it lets you live your childhood dream of blowing up and slashing a bunch of enemies as a massive, hulking Space Marine. It's not easy being a Space Marine though - and particularly if... | Read more »
Gopogo guide - How to bounce like the be...
Nitrome just launched a new game and, as to be expected, it's a lot of addictive fun. It's called Gopogo, and it challenges you to hoparound a bunch of platforms, avoiding enemies and picking up shiny stuff. It's not easy though - just like the... | Read more »
Sago Mini Superhero (Education)
Sago Mini Superhero 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: KAPOW! Jack the rabbit bursts into the sky as the Sago Mini Superhero! Fly with Jack as he lifts impossible weights,... | Read more »
Star Wars: Galaxy of Heroes guide - How...
Star Wars: Galaxy of Heroes is all about collecting heroes, powering them up, and using them together to defeat your foes. It's pretty straightforward stuff for the most part, but increasing your characters' stats can be a bit confusing because it... | Read more »
The best cooking apps (just in time for...
It’s that time of year again, where you’ll be gathering around the dinner table with your family and a huge feast in front of you. [Read more] | Read more »
Square Rave guide - How to grab those te...
Square Rave is an awesome little music-oriented puzzle game that smacks of games like Lumines, but with its own unique sense of gameplay. To help wrap your head around the game, keep the following tips and tricks in mind. [Read more] | Read more »

Price Scanner via

Sunday roundup of Holiday weekend Mac sales:...
Take up to $500 off MSRP on the price of a new Mac at B&H Photo today as part of their Black Friday/Holiday weekend sale. Shipping is free, and B&H charges NY tax only. These prices are... Read more
Holiday weekend: Apple Watch on sale for $50-...
B&H Photo has the Apple Watch on sale today for $50-$100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - Apple Watch Sport: $50 off - Apple Watch: $50-$100 off Read more
Holiday weekend: iPad Air 2s on sale for up t...
B&H Photo has iPad Air 2s on sale for up to $80 off MSRP including free shipping plus NY sales tax only: - 16GB iPad Air 2 WiFi: $459 $40 off - 64GB iPad Air 2 WiFi: $569 $30 off - 128GB iPad Air... Read more
Holiday weekend Mac sales roundup: B&H Ph...
B&H Photo continues to have all new Macs on sale for up to $500 off MSRP as part of their Black Friday/Holiday weekend sale. Shipping is free, and B&H charges NY tax only: - 15″ 2.2GHz Retina... Read more
iMobie Releases its Ace iOS Cleaner PhoneClea...
iMobie Inc. has announced the new update of PhoneClean 4, its iOS cleaner designed to reclaim wasted space on iPhone/iPad for use and keep the device fast. Alongside, iMobie hosts a 3-day giveaway of... Read more
U.S. Cellular Offering iPad Pro
U.S. Cellular today announced that it is offering the new iPad Pro with Wi-Fi + Cellular, featuring a 12.9-inch Retina display with 5.6 million pixels — the most ever in an iOS device. U.S. Cellular... Read more
Newegg Canada Unveils Black Friday Deals for...
Newegg Canada is offering more than 1,000 deep discounts to Canadian customers this Black Friday, available now through Cyber Monday, with new deals posted throughout the week. “Black Friday is... Read more
Black Friday: Macs on sale for up to $500 off...
BLACK FRIDAY B&H Photo has all new Macs on sale for up to $500 off MSRP as part of their early Black Friday sale including free shipping plus NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $... Read more
Black Friday: Up to $125 off iPad Air 2s at B...
BLACK FRIDAY Walmart has the 16GB iPad Air 2 WiFi on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available): - 16GB iPad Air 2 WiFi: $399, save $... Read more
Black Friday: iPad mini 4s on sale for $100 o...
BLACK FRIDAY Best Buy has iPad mini 4s on sale for $100 off MSRP on their online store for Black Friday. Choose free shipping or free local store pickup (if available): - 16GB iPad mini 4 WiFi: $299.... Read more

Jobs Board

Specialist *Apple* /Mac Desktop - University...
…technical support, expertise and user training for a variety of Apple /Macintosh hardware, software and devices.Researches, analyzes and resolves complex Apple Read more
*Apple* Site Security Manager - Apple (Unite...
# Apple Site Security Manager Job Number: 42975010 Culver City, Califo ia, United States Posted: Oct. 2, 2015 Weekly Hours: 40.00 **Job Summary** The Apple Site Read more
WiSE *Apple* Pay Quality Engineer - Apple (...
# WiSE Apple Pay Quality Engineer Job Number: 44313381 Santa Clara Valley, Califo ia, United States Posted: Nov. 13, 2015 Weekly Hours: 40.00 **Job Summary** Join our Read more
Holiday Retail Associate with *Apple* Knowl...
…and assertive.Someone who can troubleshoot iOS devices (iPhone and iPad) and Apple Mail issues.Someone who can offer solutions.Someone who can work weekends.Someone with Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
Summary:Assist in providing strategic direction and technical leadership within the Apple portfolio, including desktops, laptops, and printing environment. This person Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.