【问题标题】:Why clang-tidy suggests to add [[nodiscard]] everywhere?为什么 clang-tidy 建议在任何地方添加 [[nodiscard]] ?
【发布时间】:2021-07-07 14:56:56
【问题描述】:

我有一个 C++ 项目,其中clang-tidy 建议在任何地方添加[[nodiscard]]。这是一个好习惯吗?我的理解是 [[nodiscard]] 只有在忽略返回值对程序可能是致命的情况下才应该使用。我有一个对象Car,它有一个成员const unsigned int m_ID。吸气剂 unsigned int getID() 应该有 [[nodiscard]] 吗? clang-tidy 建议这样做。

编辑:

当然,我不想忽略 getter。但是
我的观点是,如果每个返回内容的函数都应该有一个[[nodiscard]],那么属性[[nodiscard]] 无论如何都是多余的。编译器可以简单地检查所有返回值的函数。

【问题讨论】:

  • 为什么要忽略 getter 函数返回的值?
  • 是的,它应该有 [[nodiscard]],因为丢弃 getter 的返回值没有任何意义,如果这样做可能是一个错误。
  • 我认为这条规则没有意义,[[nodiscard]] 应该只用于那些实际上不应该被丢弃的东西。 (否则它实际上没有任何意义,因为所有功能都有它)
  • [[nodiscard]] 的目的不仅是为了防止您忘记处理返回值(因为它在某种程度上很重要),而且如果您编写愚蠢的代码也会对您大喊大叫。为什么你会忽略 getter 的返回值?
  • 这不仅是因为忽略返回值将是“致命的”。这是因为忽略返回值没有任何意义并且可能是一个错误。如果一个方法或函数的唯一影响是它的返回值,那么唯一明智的选择是获取返回值或根本不调用该函数。

标签: c++ clang clang-tidy nodiscard


【解决方案1】:

这个选项显然是"modernize-use-nodiscard", so you can deactivate that if you prefer

应注意,此选项概​​述的规则不是C++ 标准委员会他们自己 用于何时申请[[nodiscard]] 的规则。 Those rules being:

应该加在哪里:

  • 对于现有的 API
    • 不使用返回值总是一个“大错误”(例如,总是导致资源泄漏)
    • 不使用返回值是麻烦的根源,而且很容易发生(不明显有问题)
  • 对于新的 API(尚未加入 C++ 标准)
    • 不使用返回值通常是一个错误。

在以下情况下不应该添加:

  • 对于现有的 API
    • 至少对于某些输入,不使用返回值是一种可能/常见的编程方式
      • 例如 realloc(),当新站点 [原文] 为 0 时,它的行为就像是免费的
    • 不使用返回值是没有意义的,但不会造成伤害,而且通常不是错误(例如,因为程序员打算要求更改状态)。
    • 它是一个 C 函数,因为它们的声明可能不受 C++ 实现的控制

这就是为什么像operator new 这样的函数是[[nodiscard]],而像optional::value 这样的函数不是。你的代码有一个小错误和你的代码从根本上被破坏是有区别的。 [[nodiscard]],就委员会而言,是为后者服务的。

请注意,容器 empty 方法是一种特殊情况。它们似乎符合“不使用[[nodiscard]]”的模式,但是因为emptynameclear 的名称相似,如果不使用返回值empty,您打算致电clear的可能性很大。

显然,这不能仅从声明中得知,因此 Clang-Tidy 无法实现所述规则。

【讨论】:

    【解决方案2】:

    为什么 clang-tidy 建议在任何地方添加 [[nodiscard]]?

    clang-tidy 不建议添加 [[nodiscard]] everywhere。检查的documentation 中描述了建议的情况。

    这是一个好习惯吗?

    是的,当丢弃结果可能是错误时,使用 [[nodiscard]] 是一种很好的做法。这种情况经常发生。

    getter unsigned int getID() 应该有 [[nodiscard]] 吗?

    你能想象在不使用返回值的情况下调用 getter 的任何用例吗?如果您确定这种情况不存在,那么您应该使用 [[nodiscard]]。我认为在所描述的示例中不存在这种情况。

    我的理解是 [[nodiscard]] 应该只在忽略返回值可能对程序致命的情况下使用。

    这是一个相当保守的理解。如果您不同意,可以禁用相关检查。

    【讨论】:

      猜你喜欢
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      • 2013-01-07
      • 2018-04-25
      • 2020-01-31
      • 1970-01-01
      相关资源
      最近更新 更多