首页 > 解决方案 > 是在 C++17 中函数必须是“noexcept”吗?

问题描述

在优化代码的某些部分时,我决定检查是否可以将某些方法声明为noexcept,这归结为我对<cmath>.

因此,我决定检查我正在使用的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它们的重要性,至少在我目前使用的实现中。

但是,我无法确定这是否是标准要求的保证行为。所以,我想知道它是否是必需的行为。如果不是,那么不要求他们这样做的动机是noexcept什么?

通常的参考资料 cppreference.com没有列出noexcept这些功能(参见这个,比较)。可能,与 C 的兼容性会引起一些混乱;但是,我找不到令人信服的逻辑,因为<cmath>显然使用了 C++ 头文件,而不是 C 兼容头文件。

标签: c++c++17c++-standard-librarynoexcept

解决方案


[res.on.exception.handling]/5状态:

实现可以通过添加非抛出异常规范来加强非虚拟函数的异常规范。

它们不是必须noexcept,但允许实现标记它们noexcept。您所看到的是您的实现选择将它们标记为这样,但 cppreference 没有标记它们,因为它们不是必需的。

如果不是,那么不要求他们成为 noexcept 的动机是什么?

通常的 Lakos 规则适用 - 其中一些函数具有狭窄的合同,因此实现可以假设选择抛出合同等。


推荐阅读