The commonly accepted wisdom in C++ these days is that exception specifications aren’t worth bothering with. While it’s certainly the case that they could be substantially improved to provide more utility, I’m not so dismissive of what they do offer: an assertion that a function fails only in the ways it advertises that it can. In this respect, the exception specification is much like a specialized assert. And like assert, they are valuable as a debugging aid.
If an unexpected exception occurs in a codebase that has made thorough and appropriate use of exception specifications, the exception isn’t likely to propagate far before it results in the program being terminated. Without exception specifications, the exception would propagate all the way up to main before terminating the program. The difference is in the call stack you get from a debugger when termination happens: the nearer termination is to the point at which the unexpected exception was thrown, the easier it will be to find where and why that happened.
If the exception propagates all the way back to main, the call stack doesn’t give you much useful information. You can hope that the exception itself is sufficiently specific as to give you a clue about where it came from; beyond that, your best hope is a debugger that can be configured to break automatically when an exception is thrown.
The other service provided by exception specifications is simply documentation. One might reasonably suggest that this service is better provided by actual documentation; but that is only true to the extent that such documentation is complete and accurate. The fact is that assessment of the exceptions that can be thrown by a function requires a rather thorough inspection of that function an all the ones it calls. And when any of this code changes, the documentation needs to be checked to ensure it remains accurate. Unfortunately, that is all too easy to overlook—even with embedded documentation schemes such as that supported by Doxygen. There is a far more compelling interest in updating something that is likely to crash your program if it is wrong. And an accurate exception specification makes documentation that much easier.
However, as Sutter points out, exception specifications are likely to impact performance negatively. Like the validation done in an assert, the exception specification imposes additional run-time checking. assert, of course, is a macro—and that means that by twiddling a preprocessor symbol, the checking it does can be made to go away completely. And there’s no reason the same solution can’t be employed to toggle the presence of exception specifications: rather than use throw directly when writing an exception specification, use a macro that can be redefined to make the whole business go away when that’s desirable (e.g., optimized builds).