【问题标题】:C++ exception, undefined behavior and noexceptC++ 异常、未定义行为和 noexcept
【发布时间】:2016-06-11 05:33:02
【问题描述】:

关于这个功能

int test(int a,int b)
{
    return a/b;
}

如果我打电话给test(2,1),什么都不会发生。
但是如果我打电话给test(2,0),它会导致未定义的行为。
结果,我应该将其定义为noexcept吗?

顺便说一句,为什么std::vector::operator[] 不是noexcept?

【问题讨论】:

标签: c++ exception undefined-behavior noexcept


【解决方案1】:

我应该将其定义为noexcept吗?

如果你愿意,你当然可以。确实,该函数不会引发异常。但是,它仍然可能因被零除而失败。

这取决于你认为noexcept 应该是什么意思。标准库似乎将其视为关键字,这意味着该函数不可能失败,而不仅仅是它不会抛出。如果您遵循他们的约定,则不应使用noexcept。但是,如果您希望 noexcept 仅表示它不会抛出,那么您应该这样做。

无论哪种方式,您都应该始终使用相同的约定。除了构造函数和赋值运算符之外,这两种方法都没有太大的好处。

【讨论】:

    【解决方案2】:

    您实际上是以错误的方式问这个问题。使用 noexcept 的决定通常应该是自上而下的(例如,这样做对函数的调用者是否重要)而不是自下而上(即基于您的函数正在执行的操作)。

    指定“不得扔”与“不得扔”是有区别的。 noexcept 适用于“不得扔”的情况,不适用于“不得扔”。但决定哪个合适取决于函数调用者的需求,而不是函数的实现方式。

    通过省略noexcept,允许提供函数的抛出版本,例如用于调试目的。 “不需要抛出”类别中的函数可以在调试期间安全地替换为抛出版本,然后在“发布”构建中使用非抛出版本。此类检查在“发布”版本中是不可取的,因为它们通常会对程序性能指标产生不利影响 - 并且在某些情况下还会导致不需要的副作用(例如,如果检查执行诸如探测调用堆栈或跟踪总内存使用程序)。

    这就是 operator[] for std::vector 不是 nothrow 的原因 - 它没有被指定为 throwing,但用 throwing 版本替换它可能有助于调试目的。如果将其指定为nothrow,则会减少开发人员在发布之前对其代码(使用标准库)进行调试的机会。

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 2021-06-06
      • 2021-10-05
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多