C++ Exception Handling

By Illco of Mayday Software Productions.

Table of contents:

Introduction

This document is intended for those in need of a transparent and nice way to handle program errors. The text will introduce a widely used method for achieving this: exception handling. The described system is available in many programming language such as Java, C++, Modula-3, etc., but here we will focus on C++ exception handling.

There are several good reasons to use exception handling. The most important thing it does is separate error-handling code from your normal code; this greatly clarifies your code. Secondly, it stimulates consequences because errors are being handled in one place and in one manner.

How it was done before

Before a system of exception handling was introduced, computer programs were certainly not error-free. Several methods were available for handling errors but only one is somewhat interesting. We will look at this system to see the benefits of exception handling.

In older systems every (interesting) function you would call would return a value indicating how well the execution went. The code that called the function would then check the return code and handle accordingly. The resulting code would be littered with extra if-statements and error-handling code. Furthermore, the return value of a function could not be used to return anything but an error code.

If you have ever written a Windows application using the Windows API you have worked with this method. Remember checking the return value of RegisterClass(...) or returning zero when everything went right in WndProc(...)? See!

The concept of exception handling

The global concept of exception handling is simple. The idea is to raise some error flag every time something goes wrong. Next, there is a system that is always on the lookout for this error flag. Third, the previous system calls the error handling code if the error flag has been spotted.

Program Flow
The raising of the imaginary error flag is simply called raising or throwing an error. When an error is thrown the overall system responds by catching the error. Surrounding a block of error-sensitive code with exception handling is called trying to execute a block.

One of the most powerful features of exception handling is that an error can be thrown over function boundaries. This means that if one of the deepest functions on the stack has an error, this error can propagate up to the upper function if there is a trying-block of code there. This allows programmers to put the error handling code in one place, such as the main-function of your program.

C++ exception handling

The designers of C++, Bell labs, extended it with exception handling structures. The commands being used relate closely to the terms used in exception handling (described above). The block of code you want to try starts with specifying the try command and surrounding the block with curly braces. Within this block, you can throw any occurring errors with the throw command. You must specify an error and this should be a class but we will get to this later. Immediately after the try-block is closed, the catch-block starts. Here the error handling code is placed. The following piece of pseudo code will show the idea:

try {
___...
___...
___throw Exception()
___...
___...
} catch( Exception e )
{
___...
___...
}

In this example, Exception is a defined class with a constructor with no parameters (as identified by the throw-call). It would be useful to have some info on what kind of error occurred. This could be done in two ways. We could define different exception-classes and throw them according to which error occurred. We also could give the class a parameter containing an error message and allow the class to display the message. Such a system will be introduced in the next section.

An exception handling system

The class we are about to design should store info about the error that occurred and the class should able to display an error message. The following code is straightforward so I will just show it. The report function will show the error some way (I'm sure you're able to do this on your own!).

class CException
{
public:
___char* message;
___CException( char* m ) { message = m };
___Report();
}

With the given class we could specify the pseudo-code above a little to really show off the power of exception handling. The functions Initialize() and Run() should be considered heavily errorous and with several sub-function-calls that could throw exceptions as well.

try {
___Initialize();
___Run();
___Shutdown();
} catch( CException e )
{
___e.Report();
}

Now all occurring errors throughout the whole program will be handled by this single catch-statement and will be shown on the display with the single Report()-statement.

Illco is a Computing Science major at the University of Groningen in the Netherlands. I have been programming for about seven years and have always had a special interest in games. If anything in this text is unclear or if you want to react: please send me some e-mail.

HOME