C++ Exception Specifications: Just Say No

Consider, if you will, C++ exception specifications. An interesting topic, and one that’s often misunderstood by game developers seeking ways to optimize their code. Suppose you declare the following function:
void Starbuck();
By default, this function could throw any C++ exception, because we haven’t informed the compiler otherwise. However, if we write
void Starbuck() throw(…);
we explicity indicate to the compiler that yes, indeed, Starbuck could throw any C++ exception. The throw notation after the function declaration is called a "C++ exception specification." Here’s a more common example:
void Starbuck() throw(X,Y);
This C++ exception specification indicates to the compiler that if Starbuck throws an exception, it will only throw objects of type X and objects of type Y. Finally, consider:
void Starbuck() throw();
This is by far the most common type of C++ exception specification. It indicates to the compiler that Starbuck won’t throw an exception. Many programmers get pretty excited by this idea of informing the compiler that a function won’t throw an exception. The reasoning goes something like this: "surely the compiler can do some better optimizations if it knows that no exception will be thrown."
This reasoning is flawed. Here’s why. What if deep inside the bowels of Starbuck() throw(), an exception does happen to be thrown? Wait a minute: "That can’t happen" you say, "I’ve told the compiler to make sure." But it can happen. Perhaps Starbuck calls Apollo(), a function provided by your friendly game middleware provider. You have no control of Apollo(). It could throw an exception, and if it doesn’t throw an exception today, it could in the future. In fact, according the C++ Standard (15.5.2), if a C++ exception is thrown that is not in the exception specification, the global function unexpected() is called, which by default terminates the program. Here’s the big catch: not only is the compiler prevented from optimizing the program given exception specifications, it probably has to add additional code to call unexpected() should an unexpected exception occur. Nasty stuff.
Here’s the important takeaway: Don’t Use C++ Exception Specifications. They don’t work the way you expect. They are a runtime semantic, not a compile time semantic. They don’t enforce anything, and they don’t allow the compiler to make the optimizations you expect.
This entry was posted in C++. Bookmark the permalink.

One Response to C++ Exception Specifications: Just Say No

  1. twittech says:

    Nice little article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s