6

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.

Anton Menshov
  • 2,266
  • 14
  • 34
  • 55
  • Note that, even for features available in C, cppreference has distinct pages for C and C++. So the link you provide is exclusively for C++, the C equivalent is [here](https://en.cppreference.com/w/c/numeric/math/sin). So, in case there was any confusion at that level, the cppreference page for `std::sin` in C++ does not have to account for C, there is a separate page for that. – François Andrieux Aug 15 '19 at 17:07
  • 1
    @FrançoisAndrieux good point. Which pretty much strengthens my question :) – Anton Menshov Aug 15 '19 at 17:09
  • 2
    The standard doesn't seem to require this but an implementation of course can provide stronger exception specifications. Note that a conforming `` could simply contain code similar to `namespace std { #include }`. Perhaps the standard doesn't bother to specify noexcept just because it wants to allow this kind of implementation. – n. m. could be an AI Aug 15 '19 at 17:21

1 Answers1

6

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

Barry
  • 286,269
  • 29
  • 621
  • 977