<cmath> 函数在 C++17 中必须是 `noexcept` 吗?
Are <cmath> functions required to be `noexcept` in C++17?
在优化代码的某些部分时,我决定检查是否可以将某些方法声明为 noexcept
,这归结为我对 <cmath>
.[=24 中的数学函数的不完整了解=]
因此,我决定检查我使用的 sin()
和 asin()
(作为示例)是否实际上是 noexcept
。
static_assert(noexcept(asin(1)));
static_assert(noexcept(sin(1)));
顺利通过,所以他们其实是noexcept
。我也在标准库实现中查看了相应的定义:
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);}
这证实了它们的 noexcept
ness,至少在我目前使用的实现中是这样。
但是,我无法找到如果那是有保证的行为,比如说,标准要求的。所以,我想知道它是否是必需的行为。如果不是,那么不要求他们 noexcept
的动机是什么?
我的usual reference cppreference.com does not list noexcept
for those functions (see this, in comparison)。可能,这里有些混乱来自与 C 的兼容性;但是,我找不到令人信服的逻辑,因为 <cmath>
显然使用 C++ headers,而不是 C-compatibility。
[res.on.exception.handling]/5 状态:
An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.
它们不需要成为noexcept
,但是允许实施来标记它们noexcept
.您所看到的是您的实现选择将它们标记为这样,但 cppreference 没有标记它们,因为它们不是必需的。
And if it is not, what is the motivation of not requiring them to be noexcept?
通常的 Lakos 规则适用 - 其中一些函数具有狭窄的契约,因此实现可以假设地选择抛出契约等。
在优化代码的某些部分时,我决定检查是否可以将某些方法声明为 noexcept
,这归结为我对 <cmath>
.[=24 中的数学函数的不完整了解=]
因此,我决定检查我使用的 sin()
和 asin()
(作为示例)是否实际上是 noexcept
。
static_assert(noexcept(asin(1)));
static_assert(noexcept(sin(1)));
顺利通过,所以他们其实是noexcept
。我也在标准库实现中查看了相应的定义:
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);}
这证实了它们的 noexcept
ness,至少在我目前使用的实现中是这样。
但是,我无法找到如果那是有保证的行为,比如说,标准要求的。所以,我想知道它是否是必需的行为。如果不是,那么不要求他们 noexcept
的动机是什么?
我的usual reference cppreference.com does not list noexcept
for those functions (see this, in comparison)。可能,这里有些混乱来自与 C 的兼容性;但是,我找不到令人信服的逻辑,因为 <cmath>
显然使用 C++ headers,而不是 C-compatibility。
[res.on.exception.handling]/5 状态:
An implementation may strengthen the exception specification for a non-virtual function by adding a non-throwing exception specification.
它们不需要成为noexcept
,但是允许实施来标记它们noexcept
.您所看到的是您的实现选择将它们标记为这样,但 cppreference 没有标记它们,因为它们不是必需的。
And if it is not, what is the motivation of not requiring them to be noexcept?
通常的 Lakos 规则适用 - 其中一些函数具有狭窄的契约,因此实现可以假设地选择抛出契约等。