[ ... ]
What? It's basically the same behavior as an assertion failure.
The exception specification is part of the function's contract,
and if it is violated, you want an assertion failure.
I find this post rather confusing. You start by seeming to say that I
was dead wrong from beginning to end...
...but then you finish by seeming to agree with what I said -- that
situations that make an exception specification useful are exceedingly
rare.
That's what happens when I try to respond to a complex question
in a limited amount of time. Basically, my initial reaction
("What?") was to your statement: "it's just behavior that almost
nobody ever really wants." IMHO, it's actually the most
desirable behavior, most of the time, because:
First, I think everyone would have to agree that exceptions
do form part of the contract of a function, at least in a number
of cases. When they don't, then exception specifications are
irrelevent. Furthermore, I'm fairly convinced that there are
two important cases where they play a role in the contract.
The first is the case when you are guaranteed an exception in
case of a specific error. Most of the time, this sort of error
reporting is better handled by return codes---if it's useful for
the contract to guarantee a certain type of error in certain
conditions, it's almost certainly because it's something the
immediate caller might want to know. There are exceptions,
however---constructors are the most obvious example. In
practice, exception specifications aren't very useful here,
since they actually specify what won't be thrown, and not what
will be thrown (and of course, even if they specified what will
be thrown, they wouldn't specify under which conditions it would
be thrown).
The second case is when the contract guarantees an absense of
exceptions. This can be very important in low level code: you
can't use the swap idiom to implement transactional semantics in
an assignment operator unless the swap function guarantees that
it will not throw. And this is precisely what C++ exception
specifications can provide: a guarantee that no matter what
happens, the function will not throw anything that is not
specified in the exception specifier. Off hand, I can't think
of a case where anything but an empty exception specifier (the
no throw guarantee) would be useful, but I suppose it could
happen: the caller is able to handle one specific type of error,
and catches that exception, but no other exception is possible.
At any, throw() is definitly a useful part of a contract, and if
the contract is violated, you want an assertion failure. And
the specified default behavior of throw() is very much like an
assert---violate the contract, and the program is terminated,
with prejudice.
Given that the only relevant use of exception specifiers *is*
guaranteeing an absense of exceptions (or maybe in some very
special cases, and absense of all but one type of exception),
I'd argue that the specified behavior of them is exactly what is
most often wanted.
In the end, I guess I'm not all that worried about whether we
agree or not, but I'm left wondering about what you think of
the OP's question: how often do you see code that really
benefits from an exception specification.
Any time you need the no throw guarantee. Destructors, swap
functions, etc. Possibly some higher level functions in a
transaction management system (the second phase of a two phase
commit?).
Regretfully, because too many people have mainly considered the
idea of applying them to my first case above, and rejected them
as useless (and they pretty much are, for that case), many
compiler implementors haven't bothered about the quality of
their implementation. (It's interesting to note that Java's
exception specifications seem mainly designed to address the
first case. With very mitigated success, IMHO.)
I'd note, in particular, that for most situations I've
encountered, that the ONLY exception guarantee that means much
is a guarantee that a particular piece of code will not throw
any exception. Unfortunately, it's absolutely _impossible_ to
write an exception specification that gives such a guarantee
-- no matter how you write it, every exception specification
says that the code in question can throw at least one
exception.
No. "throw()" guarantees absolutely that the function will
never exit via an exception. §15.4/8,9:
Whenever an exception is thrown and the search for a
handler (15.3) encounters the outermost block of a
function with an exception-specification, the function
std::unexpected() is called (15.5.2) if the
exception-specification does not allow the exception.
The function std::unexpected() may throw an exception
that will satisfy the exception-specification for which
it was invoked, and in this case the search for another
handler will continue at the call of the function with
this exception specification (see 15.5.2), or it may call
std::terminate().
and in §15.5.2/2:
The std::unexpected() function shall not return, but it
can throw (or re-throw) an exception. If it throws a new
exception which is allowed by the exception
specification which previously was violated, then the
search for another handler will continue at the call of
the function whose exception specification was violated.
If it throws or rethrows an exception that the
exception-specification does not allow then the
following happens: If the exception-specification does
not include the class std::bad_exception (18.7.2.1) then
the function std::terminate() is called, otherwise the
thrown exception is replaced by an
implementation-defined object of the type
std::bad_exception and the search for another handler
will continue at the call of the function whose
exception-specification was violated.
Thus, an exception-specification guarantees that only
the listed exceptions will be thrown. If the
exception-specification includes the type
std::bad_exception then any exception not on the list
may be replaced by std::bad_exception within the
function std::unexpected().
Note that the only thing unexpected is allowed to do is
terminate the program OR throw an exception which is listed in
the exception specifier. If no exception is listed in the
exception specifier, then all it can do is terminate.
Of course, there's no way to guarantee a function will return
normally. It can always call abort(), or exit(). Or someone
can turn the machine off, or do a "kill -9" on your process.
(Which are important considerations to keep in mind when
transactional itegrity is important, but have no effect on the
internal consistency of the program.)