Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are <cmath> functions required to be `noexcept` in C++17? [duplicate]

While optimizing certain parts of my code, I decided to check if I can declare certain methods as noexcept, which boiled down to my incomplete knowledge about math functions from <cmath>.

So, I decided to check if sin() and asin() (as examples) that I am using are, in fact, noexcept.

static_assert(noexcept(asin(1)));
static_assert(noexcept(sin(1)));

which successfully passed, so they are in fact noexcept. I also looked inside the corresponding definition in the standard library implementation:

template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename std::enable_if<std::is_integral<_A1>::value, double>::type
asin(_A1 __lcpp_x) _NOEXCEPT {return ::asin((double)__lcpp_x);}

which confirmed the noexceptness of them, at least in the implementation I am currently using.

However, I was not able to find if that is a guaranteed behavior, say, required by the standard. So, I wonder if it is or it is not the required behavior. And if it is not, what is the motivation of not requiring them to be noexcept?

My usual reference cppreference.com does not list noexcept for those functions (see this, in comparison). Probably, some confusion comes here from the compatibility with C; however, I cannot find a convincing logic as <cmath> obviously uses C++ headers, not the C-compatibility ones.

like image 607
Anton Menshov Avatar asked Aug 15 '19 17:08

Anton Menshov


1 Answers

[res.on.exception.handling]/5 states:

An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.

They are not required to be noexcept, but an implementation is allowed to mark them noexcept. What you are seeing is that your implementation chose to mark them as such, but cppreference doesn't mark them because they're not required to be.

And if it is not, what is the motivation of not requiring them to be noexcept?

The usual Lakos rule applies - some of these functions have narrow contracts, so an implementation could hypothetically choose to throw out of contract, etc.

like image 100
Barry Avatar answered Oct 12 '22 08:10

Barry