【问题标题】:When should one explicitly attribute noexcept?什么时候应该明确属性 noexcept?
【发布时间】:2020-12-22 22:44:40
【问题描述】:

什么时候应该将noexcept 属性添加到函数中?即编译器什么时候不能告诉函数抛出?是否应该对所有内容进行标记,还是有办法分辨?

我不喜欢过早优化,也不喜欢过早归因。我不知道有什么方法可以像优化时分析性能一样“分析”noexcept 的需求。

在评估需要的地方时,请评论最常见的编译器,例如MSVC、GCC 等

【问题讨论】:

标签: c++ gcc visual-c++ clang


【解决方案1】:

C++ Core Guidelines 建议基本上在代码不会抛出的任何地方使用它。这对于库来说非常重要,因为代码检查器会使用您调用的函数来查看它是否为 noexcept,否则您会收到一连串的警告。

也就是说,最重要的建议是使用swapmove 和析构函数noexcept

C++ 核心指南还建议创建默认构造函数noexcept,这通常很好,但许多模式(如pImpl idiom)通常在其默认构造函数中分配内存。因此,我通常在默认构造函数(或只接受默认参数的构造函数)上使用noexcept,但如果我知道它可以抛出,我会明确标记它nothrow(false)

如果您将默认构造函数、复制构造函数、赋值运算符、移动构造函数、移动运算符或析构函数声明为 =default,则默认为 noexcept。所有的析构函数也是隐式的noexcept

有一个概念,您可以标记 noexcept 来表示“如果这确实抛出,请继续并崩溃”。我发现这个概念有点模糊,所以在我的代码中我标记了 可以 抛出 noexcept(false) 或不指定它的东西。这通常是调用new 或初始化std 容器的东西。

【讨论】:

    【解决方案2】:

    什么时候应该将noexcept 属性添加到函数中?

    当您想要记录并强制执行函数永远不会抛出时。

    重要的是要记住,这里的错误意味着将调用std::terminate() 而不是传播异常。因此,这可能是一种悲观。

    即编译器什么时候无法判断函数抛出?

    恰恰相反:编译器必须假设一切都抛出,除非它可以证明不是这样(或被告知不是这样)。

    当它具有所需的定义时,它将能够证明它。例如,在没有 LTO 的 TU 之间,它不会。

    我不知道如何“描述”noexcept 的需求

    就像在任何其他情况下一样:您测量有无。

    对于大多数项目,致力于启用 LTO 是一种更好的处理方式。

    【讨论】:

      猜你喜欢
      • 2013-11-16
      • 1970-01-01
      • 2013-10-09
      • 2014-08-25
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      相关资源
      最近更新 更多