【问题标题】:Are <cmath> functions required to be `noexcept` in C++17? [duplicate]<cmath> 函数在 C++17 中是否必须是 `noexcept`? [复制]
【发布时间】:2019-12-22 02:41:58
【问题描述】:

在优化我的代码的某些部分时,我决定检查我是否可以将某些方法声明为noexcept,这归结为我对&lt;cmath&gt; 的数学函数了解不完整。

所以,我决定检查我使用的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);}

这证实了它们的noexceptness,至少在我目前使用的实现中。

但是,我无法找到这是否是一种有保证的行为,例如,标准所要求的。所以,我想知道它是否是必需的行为。如果不是,不要求他们成为noexcept 的动机是什么?

我的usual reference cppreference.com 没有列出noexcept 的这些功能(请参阅this, in comparison)。可能,与 C 的兼容性会引起一些混乱;但是,我找不到令人信服的逻辑,因为 &lt;cmath&gt; 显然使用 C++ 标头,而不是 C 兼容标头。

【问题讨论】:

  • 请注意,即使对于 C 中可用的功能,cppreference 也为 C 和 C++ 提供了不同的页面。因此,您提供的链接专门用于 C++,C 等效项是 here。因此,如果在该级别存在任何混淆,C++ 中 std::sin 的 cppreference 页面不必考虑 C,有一个单独的页面。
  • @FrançoisAndrieux 好点。这几乎强化了我的问题:)
  • 标准似乎没有要求这样做,但实现当然可以提供更强大的异常规范。请注意,符合标准的&lt;cmath&gt; 可能只包含类似于namespace std { #include &lt;math.h&gt; } 的代码。也许标准不会仅仅因为它想要允许这种实现而费心指定 noexcept。

标签: c++ c++17 c++-standard-library noexcept


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-03-04
    • 2017-04-04
    • 2014-08-13
    • 1970-01-01
    • 2012-01-29
    • 2015-06-02
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多