<!DOCTYPE article
  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
  "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<article>

	<articleinfo>
		<title>Using C++ Exceptions Effectively</title>
		<author>
			<firstname>Michael</firstname>
			<surname>Smit</surname>
		</author>
		<copyright><year>2006</year></copyright>
	</articleinfo>
	
	<section><title>License</title>
	<para>This document is licensed under a Creative Commons <ulink url="http://creativecommons.org/licenses/by/2.5/">license</ulink>.</para>
	</section>
	<section><title>Overview</title>
	<para>Many C++ coders ignore exceptions completely. Unfortunately, weather
	you know it or not you are programming with them all the time. Even the <function>new</function>
	operator can throw an exception and the <acronym>STL</acronym> library
	uses them extensively.</para>
	<para>This article is intended to discuss the basic exception mechanism as
	well as some best practices to help you avoid common pitfalls. If you
	are already familiar with C++ exceptions please feel free to skip the
	intro and go right to the problems. If you are really in a hurry you can
	skip right down to the conclusions.</para>
	</section>
	<section><title>Intro to C++ Exceptions</title>
	<section><title>Why do we Need Exceptions?</title>
	<para>Exceptions are a replacement for the old C error codes. For instance,
	<function>pthread_create</function> returns an integer value indicating success
	status.
	If this integer is something other than zero the developer must check
	to see which error code was returned and take corrective action.</para>
<programlisting>
	int errorCode;
	
	errorCode = pthread_create(...);
	if(errorCode != 0)
	{
		switch(errorCode)
		{
		case EAGAIN:
			...
		}
	}
</programlisting>
	<para>Why is this so bad? Well there are a number of reasons. First of all often
	you'd like to return something other than a number. In the case
	of <function>fopen</function> we get back a pointer. In this case the only way 
	to indicate an error is to return NULL.
	NULL isn't very specific as errors go so now you also need errno to find out what
	the error actually was.Finally if the calling function then wants to pass
	this error status back to its calling function, you have to translate that
	error code into another error code and start all over.</para>
	</section>
	<section><title>What is an Exception</title>
	<para>So what is the alternative? Well obviously exceptions. Exceptions are a 
	way of transmitting error information that bypasses return values and parameters.
	In exception terminology the method which has the error <emphasis>throws</emphasis>
	an exception and the code calling that method can then try to <emphasis>catch</emphasis>
	the exception.
	</para>
	<section><title>Catching an Exception</title>
	<para>For instance, although you may be used to the <function>new</function>
	operator always working, it can actually fail. As it turns out when this happens
	an exception is thrown which you can catch.</para>
<programlisting>
try{ //Indicates that we are going to 
	//try to catch exceptions in the following code
	while(true)
	{
		int *i = new int[1000000];
	}
}catch(std::bad_alloc &amp; allocationException)
{
	//do something here to recover or exit gracefully
}
</programlisting>
<para>Some operations may throw different exceptions each of which can then
be caught.
<programlisting>
try{
	someFunction();
}
catch(Exception &amp;e)
{
	//something
}
catch(OtherException &amp;oe)
{
  //something
}
</programlisting>
</para>
</section>
<section><title>Throwing an Exception</title>
	<para>You can also throw your own exceptions. An exception can be anything
	up to and including a basic data type such as an <keysym>int</keysym>.</para>
<programlisting>
void SomeClass::someMethod(char *name)
{
	if(name == NULL)
	{
		throw NullArgumentExceptionClass();
	};
};
</programlisting>
</section>
<section><title>Re-Throwing an Exception</title>
<para>You can also re-throw a caught exception in the event that you don't know what
to do with it:
<programlisting>
void someFunction()
{
	try
	{
		//code here
	}
	catch(Exception &amp;e)
	{
		//do some cleanup
		throw; //rethrow the exception
	}
};
</programlisting>
</para>
<para>When you re-throw an exception it is passed along to the next caller
up in the same way as it was passed in the first place.</para>
</section>
</section>

	<section><title>How Exceptions Work</title>
	<para>So what exactly happens when an exception is thrown? Well first of
	all, the currently executing method or function exits immediately. All destructors
	are called as they would be on a return, but the return value of the method/function
	is not set.</para>
	
	<para>If the calling method/function contains a try block with a catch
	that matches the type of the thrown exception then execution will jump directly
	to the catch block. Catch expressions are evaluated in the order declared in the same manner as
	function arguments. In other words, If class <classname>B</classname> extends
	class <classname>A</classname> then if <classname>B</classname> is thrown a 
	catch for &amp;<classname>A</classname> will match that exception.</para>
<programlisting>
void function()
{
	throw B();
};

int main()
{
	try{
		function();
	}
	catch(A &amp;exception)
	{
		//this works
	}
}
</programlisting>
	<para>Trying to catch with a non-reference <classname>A</classname> parameter
	also behaves as you would expect.</para>
<programlisting>
void function()
{
	throw B();
};

int main()
{
	try{
		function();
	}
	catch(A exception)
	{
		//this works, but the B object gets sliced down to A.
	}
}
</programlisting>
	
	<para>If there is no catch block in the calling function or method it will also terminate 
	immediately until the top-level function (usually main) is reached.
	If no catch statement is found the program will terminate.</para>
<programlisting>

void function1()
{
	throw Exception1();
};

int function2()
{
	int ret = 0;
	for(int i=0; i &lt; 3; i++)
	{
		ret++; //will only get executed once
		function1();
	}
	return ret; //will never get executed
};

int main()
{
	int a = 12;
	try
	{
		a = function2();
		cout &lt;&lt; "hello" &lt;&lt; endl; //never executed
	}
	catch(Exception1 &amp;exception)
	{
		cout &lt;&lt; "Exception thrown" &lt;&lt; endl; //executed.
	}
};
</programlisting>
	</section>
	<section><title>Catching an Exception You've Never Met</title>
	<para>Since exceptions can be anything at all it is entirely possible
	you won't know what type to put in your catch block in all cases. Fortunately
	C++ has provided a way of catching these pesky exceptions:
<programlisting>
try
{
	//some code here
}
catch(Exception &amp;e)
{
  //some code
}
catch(...) //catch any exception not yet caught
{
  //some code
}
</programlisting>
	</para>
	</section>
	<section><title>So why is This an Improvement</title>
	<para>Well first of all, an exception doesn't require you to
	try to overload the meaning of a return value to include error status.
	Second, exceptions cannot be ignored. If you ignore an exception the
	program will terminate. Finally, an exception can contain a lot more
	information that an error code. An error code can only give you a
	category of problem; An exception can be an object that gives you details.</para>
	</section>
</section>
<section><title>Problems With C++ Exceptions</title>
<section><title>Dangling Resources</title>
<para>The biggest problem with exceptions is that until they are caught
they can leave a trail of dangling resources. Although destructors are called
when a function/method is terminated by an exception, dynamic resources such as
pointers are left dangling.</para>
</section>
<section><title>Inconsistent State</title>
<para>This is pretty similar to the dangling resources problem. Objects that
don't properly plan for exceptions can be left in a state that then makes
them unusable.
<orderedlist>
	<listitem><para>Object never deallocates some resources.</para></listitem>
	<listitem><para>Object behaves in undefined ways after exception.</para></listitem>
	<listitem><para>Object is impossible to destroy after exception.</para></listitem>
</orderedlist>
</para>
<para>The worst of these problems is the last one because it makes it impossible
for the application to recover from the error, but all three are a problem.
</para>
</section>
<section><title>Exceptions in Constructors</title>
<para>When a constructor throws an uncaught exception, the compiler cannot simply call
the object's destructor since the object has not been fully constructed. 
As a result the compiler tries to clean up for you. Theoretically, all fully constructed 
sub-elements in the class have their destructor called and any memory allocated
for elements that have not been fully constructed is freed.</para>
<example><title>Throwing an Exception in a Constructor</title>
<para>This example should produce the following output:
<programlisting>
Unexceptional constructor
Exceptional constructor
Unexceptional destructor
Exception construction init
</programlisting>
</para>
<programlisting>
class Exceptional
{
public:
        Exceptional();
        ~Exceptional();
};

Exceptional::Exceptional()
{
        cout &lt;&lt; "Exceptional constructor" &lt;&lt; endl;
        throw 1;
};

Exceptional::~Exceptional() //Never Called!
{
        cout &lt;&lt; "Exceptional destructor" &lt;&lt; endl;
};

class Unexceptional
{
public:
        Unexceptional();
        ~Unexceptional();
};

Unexceptional::Unexceptional()
{
        cout &lt;&lt; "Unexceptional constructor" &lt;&lt; endl;
}

Unexceptional::~Unexceptional()
{
        cout &lt;&lt; "Unexceptional destructor" &lt;&lt; endl;
};

class InitTest
{
public:
        InitTest();
private:
        Unexceptional unexceptional;
        Exceptional exceptional;
};

InitTest::InitTest()
{
        cout &lt;&lt; "Init test constructor" &lt;&lt; endl;
}

int main()
{
        try{
                InitTest init;
        }
        catch(int i)
        {
                cout &lt;&lt; "Exception construction init" &lt;&lt; endl;
        };
};
</programlisting>
</example>
<section><title>Catching Exceptions in Initializer Lists</title>
<para>The C++ standard committee didn't like the idea that there could be
some exceptions you couldn't catch in the enclosing method. The previous
example would seem to be one. Since the constructor for <classname>Exceptional</classname> is called
automatically when building an <classname>InitTest</classname> object it would seem there is no
good way of catching the exception.</para>
<para>As a result the C++ committee came up with this:
<programlisting>
A::A()
try
:B(...), C(...)
{
	//constructor code
}
catch(...)
{
	//exception code
};
</programlisting>
</para>
<para>The idea is that any exception thrown in the initializer list is caught
by the catch block. The behavior is similar to that for a normal catch block
except <emphasis>the exception is re-thrown even if you handle it.</emphasis>
As a result, A is still not considered fully constructed.
</para>
<para>Unfortunately, what happens next differs by compiler. If we 
use an initializer try block to catch <classname>Exceptional</classname>'s exception:
<programlisting>
InitTest::InitTest()
try
: exceptional()
{
        cout &lt;&lt; "Init test constructor" &lt;&lt; endl;
}
catch(int i)
{
        cout &lt;&lt; "Exception in initializer list" &lt;&lt; endl;
};
</programlisting>
</para>
<para>Under gcc you get this output (Exceptional is not destroyed):
<programlisting>
Unexceptional constructor
Exceptional constructor
Unexceptional destructor
Exception in initializer list
Exception construction init
</programlisting>
Under Visual Studio .NET you get this output (Exceptional is now destroyed):
<programlisting>
Unexceptional constructor
Exceptional constructor
Unexceptional destructor
Exception in initializer list
Exceptional desctructor
Exception construction init
</programlisting>
</para>
<para>TBD. What does the standard say?</para>
</section>
<section><title>Exception in Constructor With New</title>
<para>The compiler should clean up any memory allocated by the new operator
if the constructor for the object being created throws an exception. In other
words I should not have to destroy <varname>ptr</varname> in the following:
<programlisting>
int main()
{
	Exceptional *ptr;
	
	try{
		ptr = new Exceptional();
	}
	catch(int i)
	{
	}
};
</programlisting>
</para>
</section>
<section><title>Exception in Constructor of a Static Object</title>
<para>What happens when you declare a static variable and the constructor throws 
an exception? Well you can't catch it so as with other uncaught exceptions you
get a program crash.</para>
</section>
</section>
<section><title>Exceptions in Destructors</title>
<para>You may be wondering what happens when an exception is thrown from a destructor. 
Any sub-elements in the object being destroyed automatically have their destructors 
called and the memory for the object is deallocated. Obviously it is still possible
to have dangling pointers if you are not careful.</para>
<para>The problem arises when an exception is thrown which causes a destructor to
run which in turn throws its own exception. In this case the program terminates.</para>
<para>The following example should produce this output:
<programlisting>
Unexceptional constructor
Unexceptional constructor
ExceptionalDesctruct constructor
ExceptionalDestruct destructor
Unexceptional destructor
Unexceptional destructor
Caught exception
</programlisting>
</para>
<programlisting>
class Unexceptional
{
public:
        Unexceptional();
        ~Unexceptional();
};

Unexceptional::Unexceptional()
{
        cout &lt;&lt; "Unexceptional constructor" &lt;&lt; endl;
}

Unexceptional::~Unexceptional()
{
        cout &lt;&lt; "Unexceptional destructor" &lt;&lt; endl;
}

class ExceptionalDestruct
{
public:
        ExceptionalDestruct();
        ~ExceptionalDestruct();
private:
        Unexceptional unexceptional;
};

ExceptionalDestruct::ExceptionalDestruct()
{
        cout &lt;&lt; "ExceptionalDesctruct constructor" &lt;&lt; endl;
}

ExceptionalDestruct::~ExceptionalDestruct()
{
        cout &lt;&lt; "ExceptionalDestruct destructor" &lt;&lt; endl;
        throw 1;
};

void myFunction()
{
        Unexceptional unexceptional;
        ExceptionalDestruct exceptional;
};


int main()
{
        try
        {
                myFunction();
        }
        catch(int i)
        {
                cout &lt;&lt; "Caught exception" &lt;&lt; endl;
        }
};
</programlisting>
<section><title>Exception in Destructor of a Static Object</title>
<para>What happens when you declare a static variable and the destructor throws 
an exception? As with static constructor exceptions the application will crash.</para>
</section>
</section>
<section><title>Exception Specifications</title>
<para>One oft-ignored feature of the C++ language is exception specifications.
I'll spill the beans up front here: don't use them. Ever. If you are curious 
as to why feel free to continue.</para>
<section><title>What are They?</title>
<para>One of the problems with exceptions is that there is no way to
know which exceptions are thrown by which methods. In the case of spotty documentation
it can be difficult to figure out what to put in your catch block. In general
you pretty much have to assume anything at all could throw anything.</para>
<para>Exception specifications attempt to solve this problem by allowing you
to declare what exceptions a method throws as part of the method declaration.
<programlisting>
class MyClass{
public:
	void myMethod() throw(Exception1, Exception2);
	void myMethod2() throw(); //This can't throw anything
};
</programlisting>
</para>
<para>On the face of it this looks like the best thing since sliced bread
and a nice analog of Java exception specifications. Unfortunately there are 
some problems.</para>
</section>
<section><title>Problems</title>
<para>First of all, Microsoft Visual Studio .NET doesn't support any exception
declarations other than <keysym>throw()</keysym>. They compile but are ignored which
results in exception specifications becoming glorified comments.</para>
<para>Even worse, since these specifications have to be re-declared in the header
and source file for this an every extending class, it is highly likely that as you
update them they
will end up as incorrect glorified comments.</para>
<para>Now if you have gcc you may be inclined to laugh at Microsoft and go on
your merry way. Calm down and try this example:
<programlisting>
class MyClass
{
public:
        void myMethod() throw();
        void myOtherMethod() throw(Exception);
};

void MyClass::myMethod() throw()
{
        myOtherMethod(); //clearly throws Exception
};

void MyClass::myOtherMethod() throw(Exception)
{
        throw Exception();
};
</programlisting>
</para>
<para>This blatant violation of the contract doesn't warrant a peep from
the compiler. So what's going on? This is the fundamental problem with C++ exception specifications:
<emphasis>they are only checked at runtime</emphasis>. When an undeclared exception is thrown 
the default behavior is to immediately terminate the program.</para>
<para>It is possible to override this behavior by defining std::unexpected, but
since this is one global function for the entire application (possibly containing
libraries you did not write) basically all this does is let you pull the trigger
yourself.</para>
<para>So to summarize, the best case scenario before was that you would use (...)
to catch unknown exceptions and attempt to go on your merry way; with exception specifications
the best case scenario is that you terminate your program completely. In fact this
sounds a lot like the old worst case scenario before exception specifications.</para>
</section>
</section>
<section><title>Testing Exception Handling Code</title>
<para>This is an issue which programmers in other languages talk about a lot.
C++ programmers less so. The reason of course is that it is often very difficult
to force an exception to happen given that the exception happens in only exceptional
circumstances. For instance, how do you test your code for handling a failed <methodname>new</methodname>
call?</para>
</section>
</section>
<section><title>Conclusions and Guidelines</title>
<section><title>Throwing Exceptions</title>
<section><title>When Should I Throw an Exception?</title>
<orderedlist>
<listitem><para>Exceptions should only be thrown in exceptional circumstances to indicate
an error.They should <emphasis>never</emphasis> be used
as a glorified goto statement for passing results through a call hierarchy.</para></listitem>
<listitem><para>Exceptions should never be thrown from a destructor.
There is very little a developer can do with a destructor exception and they can easily
cause the program to abort when a cascading destructor sequence throws multiple exceptions.
Also, destructor exceptions are very difficult to catch when the object has been statically
declared.</para></listitem>
</orderedlist>
</section>
<section><title>What Should I Throw as an Exception?</title>
<orderedlist>
<listitem><para>Always throw an object. Non-object exceptions are almost as 
bad as return codes and usually result in a lot of (...) catch statements.</para></listitem>
<listitem><para>All thrown objects should come from the same object hierarchy.If
all exceptions in your library extend from <classname>MyException</classname> then
the developer can always get some sort of type information about any exception you
throw.</para></listitem>
<listitem><para>The exception hierarchy should use virtual methods. I hope this goes
without saying.</para></listitem>
<listitem><para>That hierarchy is ideally std::exception. std::exception is already
defined for you and all the STL exceptions derive from it so why not use it?</para></listitem>
</orderedlist>
</section>
<section><title>When Should I Re-throw an Exception?</title>
<para>For the most part there are two main reasons to re-throw exceptions
<orderedlist>
	<listitem><para>You would like to add some annotation to the exception that is
	not available in the throwing method.</para></listitem>
	<listitem><para>You need to do clean resources in the event of an exception, but
	cannot handle it.</para></listitem>
</orderedlist>
</para>
</section>
</section>
<section><title>Handling Exceptions</title>
<section><title>What is an Exception-Safe Object?</title>
<para>When designing exception safe code there are three ways an object can
fail:
<orderedlist>
<listitem><para>Object goes into an undefined state. May be indestructible.</para></listitem>
<listitem><para>Object goes into an error state, but can be destroyed.</para></listitem>
<listitem><para>Object stays in a defined state and can continue being used.</para></listitem>
</orderedlist>
</para>
<para>Basically you want to aim for the third and failing that go for the second.
Most code you run across falls into category one which makes using exceptions difficult.</para>
</section>
<section><title>When Should I Catch an Exception?</title>
<orderedlist>
<listitem><para>Whenever you allocate resources that will result in a dangling reference
if an exception is thrown, that code should be enclosed in a <keysym>try</keysym>
block. This should be rare if you use the strategies suggested in (TBD)</para></listitem>
<listitem><para>Whenever an exception might be thrown that would be impossible
to handle gracefully in the calling method. The exception should either be caught
and handled or caught and replaced by a new, more appropriate exception. Obviously
C++ doesn't make this easy since anything can theoretically throw an exception of any type.</para></listitem>
<listitem><para><function>main</function> or thread functions should always catch all exceptions.
It is generally good practice to catch and at least report any exceptions thrown
from within <function>main</function> or the top level function for a thread. In either case
the execution thread simply aborts if the exception is uncaught leaving the user
to wonder what happened.</para></listitem>
</orderedlist>
</section>
<section><title>Using Destructors to Write Exception Safe Code</title>
<para>Try/catch blocks can really clutter up a piece of code. This is particularly
true in C++ where any function,method, or operator can throw an exception. Fortunately
C++ provides a mechanism for writing exception-safe code in the form of destructors.</para>
<section><title>Resource Managers and std::auto_ptr&lt;T&gt;</title>
<para>Resource managers are static objects that encapsulate a dynamic resource. The
destructor of the resource manager cleans up that resource. Using a resource manager
in a method means that if an uncaught exception is thrown dynamic resources are cleaned
up automatically.</para>
<para>The C++ STL actually provides a resource manager for pointers called <classname>std::auto_ptr</classname>.
<classname>auto_ptr</classname> uses overloaded <methodname>operator*</methodname> and <methodname>operator-></methodname>
methods to mimic a pointer's behavior so that is can be used very much in the same way.
</para>
<programlisting>
Widget *some_function()
{
	auto_ptr&lt;Widget&gt; widget;
	
	widget->some_method();
	...
	//widget.release() releases control of the dynamic resource
	return widget.release();
}
	
</programlisting>
</section>
<section><title>Smart pointers and Reference Counting</title>
<para>As resource managers go <classname>auto_ptr</classname> is pretty brain dead.
There are a whole class of resource managers called smart pointers some of which
can count the number of outstanding references of a particular dynamic resource
and destroy it only after the last reference is destroyed.</para>
</section>
</section>
<section><title>Catch by Reference or Value</title>
<para>Always catch by reference for the same reasons that methods taking virtual
classes should use reference parameters.</para>
</section>
</section>
<section><title>Exception Specifications</title>
<section><title>When Should I use Them?</title>
<para>Never. At best they are useless and at worst they are actively misleading.</para>
</section>
</section>
</section>
</article>

