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:
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.