Different uses of noexcept

Viewed 69

In the book The C++ Programming Language it is written that you can declare a function to be conditionally noexcept. For example:

template<typename T>
void my_fct(T& x) noexcept(std::is_pod<T>::value);

noexcept takes a predicate that must be a constant expression (in the example std::is_pod<T>::value).

However, in the book it is also written:

The noexcept() operator takes an expression as its argument and returns true if the compiler knows that it cannot throw and false otherwise.

Taking this into account, consider:

constexpr bool f() { return true; }

void g() noexcept(f())
{
    f();
}

Is g() marked as noexcept or not? I see two possibilities:

  1. The call f() is evaluated at compile-time because it is marked constexpr, it returns true and as a result g() is marked noexcept.
  2. The compiler cannot determine that f() cannot throw an exception because f() is not marked noexcept. As a result g() is not marked noexcept.

Which one does happen? How can I select one or other behavior for noexcept?

2 Answers

The language grammar allows only the noexcept specifier to appear in that position.

Therefore your first point is correct. g() will be marked noexcept, because f() returns true.

The noexcept operator must appear in an expression. The noexcept specifier takes an expression as argument, so if one wants to have a function be noexcept depending on whether a certain expression is noexcept, one has to write:

void g() noexcept(noexcept(f()))
{
    f();
}

which will behave according to your second point.

Which one does happen?

1.

How can I select one or other behavior for noexcept?

Using context. Function declaration is the only context where the predicate meaning is used.

If you want to use the noexcept operator within the noexcept predicate, you need to write:

void g() noexcept(noexcept(f())) 
Related