Why is C++ std::optional::operator*() not declared as noexcept? - c++

When running a static analyzer over my code, I've come across std::optional::operator*() not being declared as noexcept. It would seem to me that there is no good reason for the operator to throw as one is expected to verify if the optional is engaged PRIOR to fetching its value.
Is anyone able to clarify why this decision was made?

Found justification as to why noexcept was not used, buried within the std::optional proposal n3672:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3672.html
The observers that access the contained value — operator* and
operator-> — are not declared as noexcept(true) even though they have
no good reason to throw. This is because they impose a precondition
that optional object shall be engaged, and as per observations from
N3248[6], library vendors may need to use exceptions to test if the
implementation has all the necessary precondition-checking code
inside. These observer functions are still required not to throw
exceptions.

Related

Preferred way to specify that function throws exception

I want to document that function throws exception
Are those samples below equivalent?
What is the preferred way?
void validate_input(const std::string &on) throw(...)
void validate_input(const std::string &on) noexcept(false)
// throws std::runtime_error if input is invalid
void validate_input(const std::string &on)
The third one.
You should definitely write a comment explaining what exceptions the function may throw, and what that means when it does.
Otherwise, people using your function have to examine its implementation and work it out for themselves. Every time. Not good!
Put the comment alongside the ones you already have (right??) listing preconditions and postconditions and explaining what the function does.
Are those samples below equivalent?
throw(...) is different from the two others, is deprecated and going to be removed in a future standard.
Second and third are mutually equivalent (exceptions apply 1) as far as the language is concerned. Lack of exception specification implies that the function may throw (also 1).
Documenting what exceptions are thrown and in which situations is a good practice.
1 Deallocation functions and destructors are implicitly non-throwing but can be explicitly specified otherwise. Implicitly generated or defaulted special member functions etc. may "inherit" specification from base / members i.e. they are implicitly non-throwing unless a base or a member is potentially throwing.

noexcept practice for style and performance?

I began adding noexcept to my code, but I'm wondering if it's even wise to bother adding it to inline functions. I'm assuming the optimizer would omit the runtime check when it's clearly unneeded... but from a human/style perspective, is it worth adding noexcept to trivial functions like getters, settings, increment functions, etc? I'm thinking it's visual clutter for something totally obvious. I'm debating a rule that inline functions get to omit noexcept, but normal .hpp/.cpp functions have to have it if they don't throw.
Secondly, I have a large amount of code that can't throw at all because it has no allocations (in my chess engine), that includes no STL or anything else that might fail, so success is always guaranteed. Wouldn't noexcept slow it down due to the runtime check? Does anyone use a macro to switch between using noexcept for DEBUG builds, but swap to throw() for release, which is compile-time only?
If your inline function is a leaf-level function, i.e. It calls no functions itself, then in theory a compiler could determine that it won't throw and omit whatever exception handling may have been generated otherwise. So performance-wise, it may prove unnecessary.
Having said that, you shouldn't expect to see a performance reduction from adding noexcept. Whatever code that would have to have been generated to handle propagation of exceptions shouldn't become any more complicated by adding noexcept. It's worth noting that a compiler is permitted to omit unwinding the stack entirely if an exception is thrown from a noexcept function. This is largely where the direct benefits of noexcept come from.
As for a style recommendation, first and foremost, consider whether noexcept would be a useful part of your interface. Things such as move operations can benefit greatly from being noexcept for algorithmic reasons, but besides those, it's really up to you to decide where noexcept has value for you, your interface and the users of your interface.
If this doesn't answer your question, feel free to comment on my answer and I will clarify further.
Sidenote: throw(), as well being deprecated in C++11, doesn't give the same guarantees as noexcept. If an exception is thrown through a function declared throw(), the stack must be completely unwound up to the caller of that function. See 15.5.2.1 in version N3337 of the C++ standard for reference to this behaviour.
By adding noexcept or noexcept(true) specifier to function, you ask compiler to add run-time check and call std::terminate. So you have a small performance hit. You should gain something from it or I can see no sence otherwise. Standard library has traits:
is_nothrow_constructible,
is_nothrow_default_constructible,
is_nothrow_move_constructible,
is_nothrow_copy_constructible,
is_nothrow_assignable,
is_nothrow_move_assignable,
is_nothrow_copy_assignable,
is_nothrow_destructible.
Containers in standard library is known to use these traits on contained types to perform optimization (move instead of copy). Maybe some other optimizations, I don't know about. This make sense for me to add noexcept specifier to appropriate constructor or assignment operator (of course if they really don't throw), that these traits will return true, and get performance boost, when using your class with standard containers.
I don't think that adding noexcept to ordinary function like getter or setter is a good idea: you get performance hit and gain nothing.
If your code doesn't throw and doesn't use standard library - my advice: do not use noexcept at all.

What is noexcept useful for?

I saw that C++ 11 added the noexcept keyword. But I don't really understand why is it useful.
If the function throws when it's not supposed to throw - why would I want the program to crash?
So when should I use it?
Also, how will it work along with compiling with /Eha and using _set_se_translator? This means that any line of code can throw c++ exception - because it might throw a SEH exception (Because of accessing protected memory) and it will be translated to c++ exception.
What will happen then?
The primary use of noexcept is for generic algorithms, e.g., when resizing a std::vector<T>: for an efficient algorithm moving elements it is necessary to know ahead of time that none of the moves will throw. If moving elements might throw, elements need to be copied instead. Using the noexcept(expr) operator the library implementation can determine whether a particular operation may throw. The property of operations not throwing becomes part of the contract: if that contract is violated, all bets are off and there may be no way to recover a valid state. Bailing out before causing more damage is the natural choice.
To propagate knowledge about noexcept operations do not throw it is also necessary to declare functions as such. To this end, you'd use noexcept, throw(), or noexcept(expr) with a constant expression. The form using an expression is necessary when implementing a generic data structure: with the expression it can be determined whether any of the type dependent operations may throw an exception.
For example, std::swap() is declared something like this:
template <typename T>
void swap(T& o1, T& o2) noexcept(noexcept(T(std::move(o1)) &&
noexcept(o1 = std::move(o2)));
Based on noexcept(swap(a, b)) the library can then choose differently efficient implementations of certain operations: if it can just swap() without risking an exception it may temporarily violate invariants and recover them later. If an exception might be thrown the library may instead need to copy objects rather than moving them around.
It is unlikely that the standard C++ library implementation will depend on many operations to be noexcept(true). The probably the operations it will check are mainly those involved in moving objects around, i.e.:
The destructor of a class (note that destructors are by default noexcept(true) even without any declaration; if you have destructor which may throw, you need to declare it as such, e.g.: T::~T() noexcept(false)).
The move operators, i.e. move construction (T::T(T&&)) and move assignment (T::operator=(T&&)).
The type's swap() operations (swap(T&, T&) and possibly the member version T::swap(T&)).
If any of these operations deviates from the default you should declare it correspondingly to get the most efficient implementation. The generated versions of these operations declare whether they are throwing exceptions based on the respective operations used for members and bases.
Although I can imagine that some operations may be added in the future or by some specific libraries, I would probably not declaration operations as noexcept for now. If other functions emerge which make a difference being noexcept they can be declared (and possible changed as necessary) in the future.
The reason that the program may crash is because noexcept tells the optimizer your code won't throw. If it does - well, there's no way to predict what will happen with optimized code.
As for MSVC++, you'd have to check what happens when they implement noexcept. From a Standard viewpoint, SEH is undefined behavior. Accessing protected memory can already crash right now.

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...

Which operations must not throw an exception in C++?

Today I learned that swap is not allowed to throw an exception in C++.
I also know that the following cannot throw exceptions either:
Destructors
Reading/writing primitive types
Are there any others?
Or perhaps, is there some sort of list that mentions everything that may not throw?
(Something more succinct than the standard itself, obviously.)
There is a great difference between cannot and should not. Operations on primitive types cannot throw, as many functions and member functions, including many operations in the standard library and/or many other libraries.
Now on the should not, you can include destructors and swap. Depending on how you implement them, they can actually throw, but you should avoid having destructors that throw, and in the case of swap, providing a swap operation with the no-throw guarantee is the simplest way of achieving the strong exception guarantee in your class, as you can copy aside, perform the operation on the copy, and then swap with the original.
But note that the language allows both destructors and swap to throw. swap can throw, in the simplest case if you do not overload it, then std::swap performs a copy construction, an assignment and a destruction, three operations that can each throw an exception (depending on your types).
The rules for destructors have changed in C++11, which means that a destructor without exception specification has an implicit noexcept specification which in turn means that if it threw an exception the runtime will call terminate, but you can change the exception specification to noexcept(false) and then the destructor can also throw.
At the end of the day, you cannot provide exception guarantees without understanding your code base, because pretty much every function in C++ is allowed to throw.
So this doesn't perfectly answer you question -- I searched for a bit out of my own curiosity -- but I believe that nothrow guaranteed functions/operators mostly originate from any C-style functions available in C++ as well as a few functions which are arbitrarily simple enough to give such a guarantee. In general it's not expected for C++ programs to provide this guarantee ( When should std::nothrow be used? ) and it's not even clear if such a guarantee buys you anything useful in code that makes regular use of exceptions. I could not find a comprehensive list of ALL C++ functions that are nothrow functions (please correct me if I missed a standard dictating this) other than listings of swap, destructors, and primitive manipulations. Also it seems fairly rare for a function that isn't fully defined in a library to require the user to implement a nothrows function.
So perhaps to get to the root of your question, you should mostly assume that anything can throw in C++ and take it as a simplification when you find something that absolutely cannot throw an exception. Writing exception safe code is much like writing bug free code -- it's harder than it sounds and honestly is oftentimes not worth the effort. Additionally there are many levels between exception unsafe code and strong nothrow functions. See this awesome answer about writing exception safe code as verification for these points: Do you (really) write exception safe code?. There's more information about exception safety at the boost site http://www.boost.org/community/exception_safety.html.
For code development, I've heard mixed opinions from Professors and coding experts on what should and shouldn't throw an exception and what guarantees such code should provide. But a fairly consistent assertion is that code which can easily throw an exception should be very clearly documented as such or indicate the thrown capability in the function definition (not always applicable to C++ alone). Functions that can possible throw an exception are much more common than functions that Never throw and knowing what exceptions can occur is very important. But guaranteeing that a function which divides one input by another will never throws a divide-by-0 exception can be quite unnecessary/unwanted. Thus nothrow can be reassuring, but not necessary or always useful for safe code execution.
In response to comments on the original question:
People will sometimes state that exception throwing constructors are evil when throw in containers or in general and that two-step initialization and is_valid checks should always be used. However, if a constructor fails it's oftentimes unfixable or in a uniquely bad state, otherwise the constructor would have resolved the problem in the first place. Checking if the object is valid is as difficult as putting a try catch block around initialization code for objects you know have a decent chance of throwing an exception. So which is correct? Usually whichever was used in the rest of the code base, or your personal preference. I prefer exception based code as it gives me a feeling of more flexibility without a ton of baggage code of checking every object for validity (others might disagree).
Where does this leave you original question and the extensions listed in the comments? Well, from the sources provided and my own experience worrying about nothrow functions in an "Exception Safety" perspective of C++ is oftentimes the wrong approach to handling code development. Instead keep in mind the functions you know might reasonably throw an exception and handle those cases appropriately. This is usually involving IO operations where you don't have full control over what would trigger the exception. If you get an exception that you never expected or didn't think possible, then you have a bug in your logic (or your assumptions about the function uses) and you'll need to fix the source code to adapt. Trying to make guarantees about code that is non-trivial (and sometimes even then) is like saying a sever will never crash -- it might be very stable, but you'll probably not be 100% sure.
If you want the in-exhaustive-detail answer to this question go to http://exceptionsafecode.com/ and either watch the 85 min video that covers just C++03 or the three hour (in two parts) video that covers both C++03 and C++11.
When writing Exception-Safe code, we assume all functions throw, unless we know different.
In short,
*) Fundamental types (including arrays of and pointers to) can be assigned to and from and used with operations that don't involve user defined operators (math using only fundamental integers and floating point values for example). Note that division by zero (or any expression whose result is not mathematically defined) is undefined behavior and may or may not throw depending on the implementation.
*) Destructors: There is nothing conceptually wrong with destructors that emit exceptions, nor does the standard prohibited them. However, good coding guidelines usually prohibit them because the language doesn't support this scenario very well. (For example, if destructors of objects in STL containers throw, the behavior is undefined.)
*) Using swap() is an important technique for providing the strong exception guarantee, but only if swap() is non-throwing. In general, we can't assume that swap() is non-throwing, but the video covers how to create a non-throwing swap for your User-Defined Types in both C++03 and C++11.
*) C++11 introduces move semantics and move operations. In C++11, swap() is implemented using move semantics and the situation with move operations is similar to the situation with swap(). We cannot assume that move operations do not throw, but we can generally create non-throwing move operations for the User-Defined Types that we create (and they are provided for standard library types). If we provide non-throwing move operations in C++11, we get non-throwing swap() for free, but we may choose to implement our own swap() any way for performance purposes. Again, this is cover in detail in the video.
*) C++11 introduces the noexcept operator and function decorator. (The "throw ()" specification from Classic C++ is now deprecated.) It also provides for function introspection so that code can be written to handle situations differently depending on whether or not non-throwing operations exist.
In addition to the videos, the exceptionsafecode.com website has a bibliography of books and articles about exceptions which needs to be updated for C++11.