C++ throw() optimization - c++

According to Optimizing C++,
Use the empty exception specification (that is, append throw() to the declaration) for the functions you are sure will never throw exceptions.
What if I know that 90% of my methods won't throw an exception? It seems unconventional and verbose to append throw() to all of those methods. If not, what are the advantages? Or am I misunderstanding something here?

C++11 has introduced noexcept, throw is somewhat deprecated (and according to this less efficient)
noexcept is an improved version of throw(), which is deprecated in C++11. Unlike throw(), noexcept will not call std::unexpected and may or may not unwind the stack, which potentially allows the compiler to implement noexcept without the runtime overhead of throw().
When an empty throw specification is violated, your program is terminated; this means you should only declare your functions as non throwing, only when they have a no throw exception guarantee.
Finally you need a move constructor to be non throwing (specified with noexcept) to be able to use the r-value ref version of std::vector<T>::push_back (see a better explanation here)

The standard throw() doesn't enhance optimizability.
If a method is marked as throw() then the compiler is forced to check if an exception is thrown from the method and unwind the stack - just like if the function is not marked as throw(). The only real difference is that for a function marked throw() the global unexpected_handler will be called (which generally calls terminate()) when the exception leaves the function, unwinding the stack to that level, instead of the behavior for functions without an exception specification which will handle the exception normally.
For pre-C++11 code, Sutter & Alexandrescu in "C++ Coding Standards" suggested:
Avoid exception specifications.
Take exception to these specifications: Don’t write exception
specifications on your functions unless you’re forced to (because
other code you can’t change has already introduced them; see
Exceptions).
...
A common but nevertheless incorrect belief is that exception
specifications statically guarantee that functions will throw only
listed exceptions (possibly none), and enable compiler optimizations
based on that knowledge
In fact, exception specifications actually do something slightly but
fundamentally different: They cause the compiler to inject additional
run-time overhead in the form of implicit try/catch blocks around the
function body to enforce via run-time checking that the function does
in fact emit only listed exceptions (possibly none), unless the
compiler can statically prove that the exception specification can
never be violated in which case it is free to optimize the checking
away. And exception specifications can both enable and prevent further
compiler optimizations (besides the inherent overhead already
described); for example, some compilers refuse to inline functions
that have exception specifications.
Note that in some versions of Microsoft's compilers (I'm not sure if this behavior has changed in more recent versions, but I don't think so), throw() is treated in a non-standard way. throw() is equivalent to __declspec(nothrow) which does allow the compiler to assume that the function will not have an exception thrown and undefined behavior will result if one is.
C++11 deprecates the C++98 style exception specification and introduced the noexcept keyword. Bjarne Stroustup's C++11 FAQ says this about it:
If a function declared noexcept throws (so that the exception tries to
escape, the noexcept function) the program is terminated (by a call to
terminate()). The call of terminate() cannot rely on objects being in
well-defined states (i.e. there is no guarantees that destructors have
been invoked, no guaranteed stack unwinding, and no possibility for
resuming the program as if no problem had been encountered). This is
deliberate and makes noexcept a simple, crude, and very efficient
mechanism (much more efficient than the old dynamic throw()
mechanism).
In C++11 if an exception is thrown from a function marked as noexcept the compiler is not obligated to unwind the stack at all. This affords some optimization possibilities. Scott Meyers discusses the new noexcept in his forthcoming book "Effective Modern C++".

Related

Was there any version of C++ (even pre-standard) were `throw()` did not mean "cannot throw, ever"?

The questions is about history of C++: ISO standards, revised standards (with DR), even draft standards; all count as "a C++".
Is there any C++ where this property does not hold:
A function declared with an empty throw-specification throw() cannot throw an exception.
I'd like a counter example if that property does not hold.
Comments:
It goes without saying that throwing, then catching (without rethrowing) an exception inside a function, does that turn it info "a function throwing an exception". A function throwing an exception, according to its specification, throws at its caller. (If you do stuff internally it isn't part of the specification by definition.)
[Let's say that longjmp is forbidden as we have destructible objects.]
Others equivalent expressions of that question are:
Was there ever any case where the caller of a declared no-throw function had to worry about the possibility (equivalent properties):
of that function giving back control to its caller but not with a return statement
of seeing (and being able to catch) an exception thrown by that function
of having stack unwinding caused by the call of that function
of the caller not being non throwing if all other actions (other than calling that function) are non throwing
In other words, was there any C++ where the compiler could not optimize the calling function based on seeing a no-throw declaration of a called function?
C++17 has deprecated throw as a function annotation, mostly. It still allows throw() and considers it equivalent to noexcept(true). That means that throw() is an indication that a function is not supposed to exit because of an exception. And violating the noexcept(true) guarantee results in undefined behavior.
The semantics of throw() before C++17 were distinct and different. It used to be promised that a call to ::std::unexpected() would happen if the throw() clause was violated (i.e. an exception was thrown and resulted in the function exiting).
So, that means that before C++17 a compiler still needed to have some mechanism for detecting that a function did not exit from an exception, even if it was annotated with throw(). This is one of the reasons that the throw(...) function annotation (with stuff between the parenthesis) was deprecated because it would make no sense to have throw() to change to be equivalent to noexcept(true) without removing the other uses that the throw annotation had.
This code in compiler explorer demonstrates the 'unexpected exception' handler. If you change the standard requested to C++17, you'll see the code for that go away.
extern void a_different_function();
void test_function() throw ()
{
a_different_function();
}
In other words, was there any C++ where the compiler could not optimize the calling function based on seeing a no-throw declaration of a called function?
The answer to this direct question is no. But that alone is highly misleading.
A compiler's ability to do any kind of optimization on a a function which happens to call some other function that has a throw() declaration is extremely limited. The only real thing a compiler could do is eliminate the emission of any code dealing with exceptions in a caller function. But because of the nature of said code, it would really only be applicable if every function it calls does not throw. That's pretty much it as far as compiler optimizations of a function that calls a throw() function is concerned.
People often talk today about how noexcept enables optimizations. And that is true; judicious use of noexcept can cause code that operates on such functions to become more efficient. But it is important to remember that using noexcept does not enable compiler optimizations; it enables user-code optimizations.
Let's take the classic case of vector<T> for a T with noexcept move support. That case is not faster because the compiler sees what would otherwise be a series of copies and automatically changes them to moves just because the move constructor is noexcept. That isn't even possible for a compiler to do; it isn't allowed to rearrange your code like that, since this would be a detectable change depending on what your copy/move constructors do.
Such cases get faster because the source-code implementation of vector detects that T is nothrow-moveable. Having detected that case, it will then invoke a completely different codepath for shuffling elements of the vector around. The code calling the non-throwing function became faster because the calling code optimized itself, not because the compiler detected anything.
To put it simply, compiler optimization of the calling function was never really the point of throw() declarations.

C++ exception specifications being deprecated in C++11 [duplicate]

Just as I can see in cppreference, the classic "throw" declaration lists is now deprecated in C++11. What is the reason of leaving this mechanism and how should I have to specify what exceptions throws a function of mine?
For more detailed reasoning, see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3051.html
As expressed in the national body comment above, exception specifications have not proven useful in practice. There are numerous discussions of the problems with exception specifications in C++ (see, e.g., [Sutter02], [Boost03]), but the main issues are:
Run-time checking: C++ exception specifications are checked at runtime rather than at compile time, so they offer no programmer guarantees that all exceptions have been handled. The run-time failure mode (calling std::unexpected()) does not lend itself to recovery.
Run-time overhead: Run-time checking requires the compiler to produce additional code that also hampers optimizations.
Unusable in generic code: Within generic code, it is not generally possible to know what types of exceptions may be thrown from operations on template arguments, so a precise exception specification cannot be written.
In practice, only two forms of exception-throwing guarantees are useful: an operation might throw an exception (any exception) or an operation will never throw any exception. The former is expressed by omitting the exception-specification entirely, while the latter can be expressed as throw() but rarely is, due to performance considerations.
[N3050] introduces a new kind of exception specification, noexcept, the specifies that the function will not throw any exceptions. Unlike throw(), noexcept does not require the compiler to introduce code to check whether an exception is thrown. Rather, if a function specified as noexcept is exited via an exception, the result is a call to std::terminate().
With the introduction of noexcept, programmers can now express the two kinds of exception guarantees that are useful in practice, without additional overhead. This paper therefore proposes to deprecate "dynamic" exception specifications, i.e., those that are written as throw(type-id-listopt).
The answer Peter gave does not hit the actual problem of exception specifications for the implementor and user:
Exception specifications cause the program to terminate (or more precisely call termination handlers) if the implementor failed to uphold the guarantee to only throw the defined exceptions.
Thus by calling a method with a exception specification you as a library user are making your own code more prone to complete failure/termination. If the library function runs out-of-memory (std::bad_alloc), you will not get a chance to catch, but you will be terminated instead.
Thus, the original goal of communicating the most likely failure options and asking you as the user to handle them was not achieved.
As an implementor on the other side, you cannot really call any other methods any more which do not have exception specifications, because these might cause you to terminate your callers. A terrible place to be in.
The conclusion is that C++ should have just gone the way that Java did it:
If you call a method with exception specification and you have an exception specification yourself, then you must catch the exception or specify it in your own exception specification.
The compiler enforces this and no other runtime effects.
Noexcept (since C++11) suffers the same conceptual mistake, since it will also cause run-time termination if the specification is not adhered too, i.e. a method throws that was declared not to. This makes noexcept impossible to use for anything serious but the most contained cases (move constructors come to mind).
They produce slower and bigger code, because libc++ has to check if any exception propagating out of a function violates it's exception specification and call std::unexpected. This is hardly ever useful, and is worse than just documenting the exceptions a function throws yourself.

What is the difference between declaring function as __attribute__(nothrow) and `throw()`

What is the difference between declaring function as __attribute__(nothrow) and throw() when using C++ compiler with support of gnu extensions (e.g. g++ itself on Linux; C++03).
As I understand, both variants are to say compiler that this function will not throw exceptions. But implementations may be different
How will compiler use this information?
What if I will throw exception while running inside the nothrow or throw() function and this exception will go up to the function? Will function pass exception further or it will hide exception or something else?
There are several differences:
The __attribute__((...)) syntax is a gnu compiler extension, which is not exactly portable, throw() is defined by the C++ standard.
If I read it correctly, __attribute__((nothrow)) tells the compiler that it can safely assume that a function won't raise an exception, and can possibly omit emitting some code necessary for exception handling (this is on the caller side). throw(), on the other hand, implicitely catches all exceptions that arise from the function in question, and terminates the program when something is caught by calling first the unexpected exception handler, which by default calls terminate() (this happens on the callee side).
In terms of programming, throw() is the much more useful, because it can safeguard your code from being silently skipped by an exception. When I work on a project that uses exceptions, I make a point to add throw() to every single function I write.
Note, however, that neither __attribute__((nothrow)) nor throw() will cause the compiler to actually check whether no exception can be thrown. This is quite unfortunate, but the C++ standard explicitely says that the compiler must not throw an error on a throw within a function declared with throw().

Does adding `noexcept(false)` benefit the code in any way?

Recently in my code I have been explicitly writing noexcept(false) on functions that I know do throw exceptions, mainly for people reading the code. However, I am wondering if this affects the behavior of my code or the way the compiler interprets it. Does it make any difference?
Note: I am aware that destructors are implicitly noexcept and that you have to specify noexcept(false) to change that, I am wondering about other functions.
Having no exception-specifier and explicitly stating noexcept(false) are equivalent, see §15.4/12:
A function with no exception-specification or with an exception-specification of the form noexcept(constant-expression) where the constant-expression yields false allows all exceptions.
So the compiler should not distinguish between them when considering exceptions.
More importantly, there's no need for you to be tacking on noexcept(false) to your functions. As a C++ developer, you should assume every function throws by default (which is why the standard takes this stance), so you're adding no new information by writing it out; it's a waste of time for everyone.
Rather, do mark the special case where a function definitely does not throw with noexcept, and do mark the cases where a function may throw depending on some condition with noexcept(condition).
If your function is purposefully the source of some exception E, write that in your documentation.
The one case I can think of is on a destructor. I know you should never throw in a destructor. But in some cases you are stuck with code that does this and have no work around.
Since c++ automagically adds noexcept to destructors, this is the only way to undo it and prevent app terminate when the code throws.
https://github.com/chriskohlhoff/asio/issues/1216
from: https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/
The compiler will still invisibly add specification noexcept to your
destructor. And this means that the moment your destructor throws an
exception, std::terminate will be called, even if there was no
double-exception situation. If you are really determined to allow your
destructors to throw, you will have to specify this explicitly; you
have three options:
Explicitly specify your destructor as noexcept(false),
Inherit your class from another one that already specifies its destructor as noexcept(false).
Put a non-static data member in your class that already specifies its destructor as noexcept(false).
In his book More Exceptional C++, Herb Sutter has the following snippet (pp. 130):
The right answer to the Example 19-1 is much simpler:
// Example 19-4: The right solution
//
T::~T() /* throw() */
{
// ... code that won't throw ...
}
Example 19-4 demonstrates how to make a design decision instead of waffling.
Note that the throw() throws-nothing exception specification
is only a comment. That's the style I've chosen to follow, in part
because it turns out that exception specifications confer a lot less
benefit than they're worth. Whether or not you decide to actually write the specification is a matter of taste.
(emphasis mine)
So, I feel I must point out that one of the leading experts in C++ exception-safe code seems to be against the whole concept of adding exception specifications for the compiler to use (but still leaving it in the code for the programmers to understand).
Just thought it may be interesting info...

Function exceptions specification and standard exceptions - foo() throw(Exception)

In C++ you may declare function with exception specification like this:
int foo() const throw(Exception);
I found those two links:
http://www.cplusplus.com/doc/tutorial/exceptions/ and
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr156.htm
But several things end up unanswered...
Question 1: why to add exception specification? Will it bring any performance increase? What will be different for compiler? Because it seems just like an information for programmer to me.
Question 2: what will happend (what should happen) if I throw something that isn't in specification? For example:
int foo() throw(int) {
throw char; // Totally unrelated classes, not types in real
}
Question 3: function/method shouldn't throw anything. I found at least two (three, alternative syntax for different compilers) ways to specify no exception throwing:
int foo() throw();
int foo() __attribute(nothrow)__ for gcc
int foo() nothrow for visual C++
Which one is "correct"? Is there any difference? Which one should I use?
Question 4: "standart exceptions", bad_alloc,bad_cast,bad_exception,bad_typeid and ios_base::failure.
Ok bad_alloc is self explaining and I know how (and more importantly when) to use it (add to exception specification), but what about the others? None of them does really ring a bell... Which "code pieces" are they associated with? Like bad_alloc is associated with new char[500000].
Question 5: If I have exception classes hierarchy, like this:
class ExceptionFileType {
virtual const char * getError() const = 0;
};
class ExceptionFileTypeMissing : public ExceptionFileType {
virtual const char *getError() cosnt {
return "Missing file";
}
}
Should I use:
int foo() throw(ExceptionFileType);
Or:
int foo() throw(ExceptionFileTypeMissing,ExceptionFileTypeNotWritable,ExceptionFileTypeNotReadable,...)
Note: answers with references would be great. I'm looking for good practice tips.
The simple "good practice" tip is: don't use exception specifications.
Essentially the only exception to that is the possibility of an empty exception specification: throw(). That's sufficiently useful that in C++11 it's been given its own keyword (noexcept). It's generally agreed that any non-empty exception specification is a lousy idea though.
Exception specifications (other than noexcept) are officially deprecated -- and unlike many deprecated features, removing this would affect little enough source code that I think there's a good chance it really will eventually be removed (certainly no guarantee, but a pretty fair chance anyway).
As for what happens when/if you do throw an exception of a type not allowed by the exception specification: std::unexpected() gets invoked. By default, that invokes terminate(). You can use std::set_unexpected to set your own handler -- but about all you can reasonably do is add some logging before you terminate(). Your unexpected handler is not allowed to return.
Question 1
Don't bother. They were a bad idea, and were deprecated in the latest version of the language. They give no benefit to the compiler, since they are checked at runtime; if anything, they might hurt performance in some cases.
Question 2
A function called std::unexpected will be called. By default, this calls std::terminate; by default, that terminates the program. Both of these behaviours can be changed, using std::set_unexpected and std::set_terminate to install your own handler, if you really want to.
Question 3
throw() was the standard way to do it; the others are non-portable compiler extensions. In C++11, you might use noexcept, which gives a compile-time check that nothing can throw, rather than a run-time check that nothing does throw.
Question 4
bad_cast is thrown when a dynamic_cast of a reference fails.
bad_exception is thrown in some weird circumstances when an exception specification is violated.
bad_typeid is thrown if evaluating the argument to typeid involves dereferencing a null pointer
ios_base::failure is thrown by the input/output library (<iostream> etc.) when some operations fail
Question 5
If you want to allow the entire heirarchy to be thrown, then just specify the base class. But you shouldn't be using exception specifiers at all.
First, let's be very clear what an exception specification does: it's
more or less like an assert that can't be disabled, asserting that you
will not exit the function with an exception other than the ones
missing. As such, it's utility is far more limited than it would seem
at first; for the most part (and in this case, I can't imagine an
exception), the only really useful guarantee is throw(), which
guarantees that no exception will be thrown; if you want to write
exception safe code, you'll need this guarantee for a few low level
functions.
In practice, although throw() could allow some additional compiler
optimizations, the generic implementation tends to result in less
efficient code when an exception specification is used. In C++11, the
throw() has been replaced by noexcept, presumably with the hope that
compiler implementers will do something intelligent with it.
EDIT:
Since everyone (including myself) seems to have missed your question 4:
bad_alloc will be thrown by the operator new function if it cannot
allocate the memory.
bad_cast will be thrown by a dynamic_cast to a reference, in the
case where the cast fails. (A dynamic_cast to a pointer returns a
null pointer in such cases.)
bad_exception will be thrown when an exception specification is
violated, provided the exception specification allows bad_exception.
(In other words, forget it.)
bad_typeid will be thrown if you try to use typeid with a null
pointer.
ios_base::failure will be thrown if you request a stream to throw in
case of errors.
Practically speaking: you'll catch bad_alloc if you want to recover
and continue from out of memory situations. Which means not very often.
(It's very, very difficult to recover from an out of memory situation.)
For bad_cast, it's probably preferrable to use pointers, and test for
null, if you aren't sure. And there's no excuse for ever seeing a
bad_typeid. Most of the time, you'll probably want to test IO errors
explicitly, rather than configuring the stream to throw exceptions; and
exception when ios_base::badbit is set might be an exception (since it
represents a truly exceptional case of a hardward fault).
Questions 1 and 2 are addressed at some length in this question.
Questions 3 and 5 are covered by the recommendation, in the accepted answer to that question, that you don't use exception specifications at all.
Question 4 seems to be adequately addressed by typing those exception names into the search engine of your choice, or consulting the index of a good C++ book. Do you have a specific query about them?