tags:

views:

1414

answers:

4

Hello

If function or class method throws an exception it is considered to be a good practice to signify this in function's signature. I.e.

bool
some_func() throw (myExc)
{
    ...
    if (shit_happens) {
        throw myExc("shit happens");
    }
    ...
}

My should we do this ? What are the advantages (or may be disadvantages) of such programming style ?

+11  A: 

No, it is not considered good practice. On the contrary, it is generally considered a bad idea.

http://www.gotw.ca/publications/mill22.htm goes into a lot more detail about why, but the problem is partly that the compiler is unable to enforce this, so it has to be checked at runtime, which is usually undesirable. And it is not well supported in any case. (MSVC ignores exception specifications, except throw(), which it interprets as a guarantee that no exception will be thrown.

jalf
Yes. There are better ways of adding whitespace to your code than throw (myEx).
Assaf Lavie
It's not a matter of being unable to enforce it at compile time. Java compilers can enforce it, after all. It's that it's not supposed to be enforced at compile time. The function is completely allowed to throw other exceptions, but if it does, then unexpected() must be called.
Rob Kennedy
Er, unless you mean C++ compilers are unable to enforce it because the standard forbids them from doing so.
Rob Kennedy
yeah, people who just discover the exception specifications often assume that they work like in Java, where the compiler is able to enforce them. In C++, that won't happen, which makes them a lot less useful.
jalf
+1  A: 

When throw specifications were added to the language it was with the best intentions, but practice has borne out a more practical approach.

With C++, my general rule of thumb is to only use throw specifications to indicate that a method can't throw. This is a strong guarantee. Otherwise, assume it could throw anything.

Greg D
A: 

The only practical effect of the throw specifier is that if something different from myExc is thrown by your function, std::unexpected will be called (instead of the normal unhandled exception mechanism).

To document the kind of exceptions that a function can throw, I typically do this:

bool
some_func() /* throw (myExc) */ {
}
Paolo Tedesco
It's also useful to note that a call to std::unexpected() usually results in a call to std::terminate() and the abrupt end of your program.
sth
- and that MSVC at least does not implement this behavior as far as I know.
jalf
+2  A: 

Jalf already linked to it, but the GOTW puts it quite nicely why exception specification are not as useful as one might hope:

int Gunc() throw();    // will throw nothing (?)
int Hunc() throw(A,B); // can only throw A or B (?)

Are the comments correct? Not quite. Gunc() may indeed throw something, and Hunc() may well throw something other than A or B! The compiler just guarantees to beat them senseless if they do… oh, and to beat your program senseless too, most of the time.

That's just what it comes down to, you probably just will end up with a call to terminate() and your program dying a quick but painful death.

The GOTWs conclusion is:

So here’s what seems to be the best advice we as a community have learned as of today:

  • Moral #1: Never write an exception specification.
  • Moral #2: Except possibly an empty one, but if I were you I’d avoid even that.
sth