tags:

views:

182

answers:

5

Can anyone explain Exception Specifications as used in C++ ?

  • When are they used (I have rarely seen it used in code)
  • What are the pros and cons (benefits/disadvantages) of using exception specifications?
A: 

Basically, exception specifications allow the compiler to optimize the stack. The disadvantage is that it's a hell of a lot of extra spec. This means that you commonly see it in library work but not so much in working code.

I believe there's also some compile-time exception-safety thing going on, but since I've never used it, I can't be sure.

DeadMG
-1: Exception specs have absolutely nothing to do with the stack.
Billy ONeal
http://msdn.microsoft.com/en-us/library/7f10tsf4(v=VS.80).aspxI guess that when we discuss unwindable objects, that doesn't have anything to do with the stack.
DeadMG
Exception specifications _can_ allow some compiler optimization of the generated code; namely, an empty exception specification (i.e., `throw()`) can allow the compiler to omit certain otherwise necessary code based on the programmer's guarantee that the function will not throw an exception. How much it helps, I have no idea; I honestly don't think I've ever written an exception specification in my code.
James McNellis
Not suggesting that it's significant, merely that what I said was fairly correct and not a downvote case.
DeadMG
@DeadMG: No, that is plain wrong. It's true that MSVC's particular implementation of exceptions can be more efficient with an *empty* exception specification, but that's not defined that way by the standard, nor is that why exception specs were added in the first place.
Billy ONeal
Just because it's not defined to be true, nor the cause of it's addition, does not mean that this is not the case. It's also not defined that compilers can't do this optimization. I said that it "allows" the compiler to opt the stack - not that it "would". And it does allow the compiler to opt the stack. Whether or not a given compiler does is pretty irrelevant.
DeadMG
@DeadMG: Nobody says the compiler has to do anything to the stack to support exceptions. GCC, for one, does not touch the stack to support exceptions. That is not why they were added to the standard, which makes your statement incorrect.
Billy ONeal
+8  A: 

they are generally regarded as a bad idea.

THey say what a method will throw. the downside is that if that method throws anything else then your app terminates. So its a guarantee but not in the same way that JAva does it. And it adds the overhead of inspection.

pm100
+1: But nitpick: The application is not terminated; the unexpected function is called. By default that means your app is terminated, but if you have the unexpected function doing something else than that something else is what will happen.
Billy ONeal
+1 Throw specs are deprecated, but unfortunately not removed in C++0x.@Billy: +1 for the explanation. I've 2 examples I can think of, offhand, where a no-throw spec is desirable: destructors and functions/methods that are known to cross language/interop boundaries as C++ exceptions tend to not play well with others. (and I'm aware that C++0x says no-throw specs change and that current syntax is deprecated).
Nathan Ernst
@Billy: The unexpected function can do some error reporting first, but doesn't it have to terminate the program? IIRC it's forbidden to return from unexpected().
Ben Voigt
@Ben Voigt: That's why I +1'd and why it's a *minor* nitpick. Yes, the program will be terminated, but it could also be "Writes a memory dump and is terminated" or anything else you'd want to do in `unexpected`.
Billy ONeal
@Billy, @Ben: It can't return from unexpected, but it is allowed to throw a new exception. If that exception isn't in the allowed exceptions, `std::bad_exception` is tried. If *that* isn't in the allowed exceptions, then the program terminates. The end result is either an allowed exception propagates out of the function, or the program terminates.
Dennis Zickefoose
+8  A: 

When are they used (I have rarely seen it used in code)
Hopefully never as they are deprecated in the next version of C++ due for standardization next year.

What are the pros and cons (benefits/disadvantages) of using exception specifications?
They provide a way for readers of your code to know exactly what exceptions a function is allowed to throw. The problem is, that if an unexpected exception (one not in the specification) is thrown, then the program will be terminated (by default).

Billy ONeal
@James McNellis: Thanks :)
Billy ONeal
+3  A: 

The important thing to know is: exception specifications are deprecated in the next revision of C++, except for the no-throw specifier (throw()), which is basically officially saying "don't use them".

Putting throw() after a function means the function does not throw any exceptions. If it does anyway, the application will be terminated (probably - the unexpected handler is called), so the rest of your application can use that function knowing it will not throw an exception. This is can be handy for writing exception-safe code.

Example:

void MyFunction() throw() // does not throw any exceptions
{
    /* ... */
{
AshleysBrain
The no throw guarantee is very important. Especially for destructors. Though it would be nice if the compiler would warn you that you have a no throw method that potentially could throw.
Martin York
A: 

They indicate to the programmer which exceptions will be thrown from that function. They have the advantage that you have the guarantee that no other exceptions can be thrown from that function. However, there is no compile-time checking of whether the function actually throws any exceptions other than what is indicated in the throw specifier. Instead, it's checked at runtime. And if it fails, then unexpected() is called, which by default calls abort() which in turn by default terminates your program. So, unless you really want your program to die if you screw up and an unexpected exception gets thrown, it's probably a bad idea to use them.

The one place where I would actually recommend using them is on destructors. It's really bad if a destructor throws. They should never throw. So, if you use throw() on a destructor to indicate that it can't throw an exception, then you know that your program will die rather than continue in the bad state that it would be in after an exception was thrown from a destructor.

Regardless, if you use any kind of throw specifier, you have to be sure that you really do want your program to die if it's violated. So, generally-speaking, it's best not to use them.

Jonathan M Davis