In P0012R1, "Make exception specifications be part of the type system",
I see that noexcept
is now becoming a part of the function type.
I can't tell whether this will prevent noexcept(true)
functions from still being able to call noexcept(false)
functions.
Will the following code still be valid for C++17?
void will_throw() noexcept(false){
throw 0;
}
void will_not_throw() noexcept(true){
will_throw();
}
When an exception is thrown from a function that is declared noexcept or noexcept(true) , std::terminate is invoked. When an exception is thrown from a function declared as throw() in /std:c++14 mode, the result is undefined behavior. No specific function is invoked.
In contrast, noexcept(false) means that the function may throw an exception. The noexcept specification is part of the function type but can not be used for function overloading. There are two good reasons for the use of noexcept: First, an exception specifier documents the behaviour of the function.
The dynamic exception specification, or throw(optional_type_list) specification, was deprecated in C++11 and removed in C++17, except for throw() , which is an alias for noexcept(true) . We recommended you apply noexcept to any function that never allows an exception to propagate up the call stack.
The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.
According to cppreference:
Note that a
noexcept
specification on a function is not a compile-time check; it is merely a method for a programmer to inform the compiler whether or not a function should throw exceptions.
So the syntax of your code is valid, but std::terminate
will be called when executed.
noexcept(true)
functions can call noexcept(false)
functions. There will be a runtime error if an exception is thrown. The canonical example of why this is allowed is:
double hypotenuse(double opposite, double adjacent) noexcept(true)
{
return std::sqrt(opposite*opposite + adjacent*adjacent);
}
std::sqrt
will throw domain_error
if its argument is negative, but clearly that will never happen here.
(In an ideal world, it would be forbidden by default with an exception_cast
to allow it where required. The result could either be UB if an exception is thrown, or std::terminate).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With