Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a noexcept function still call a function that throws in C++17?

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();
}
like image 479
Trevor Hickey Avatar asked Sep 29 '16 06:09

Trevor Hickey


People also ask

What happens if a Noexcept function throws?

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.

What does it mean to specify a function as Noexcept false?

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.

When should you declare your functions as Noexcept?

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.

What is the point of Noexcept?

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.


2 Answers

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.

like image 189
mkaptur Avatar answered Nov 06 '22 13:11

mkaptur


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

like image 41
Martin Bonner supports Monica Avatar answered Nov 06 '22 12:11

Martin Bonner supports Monica