为什么 clang-tidy 建议到处添加 [[nodiscard]]?

Why clang-tidy suggests to add [[nodiscard]] everywhere?

我有一个 C++ 项目,其中 clang-tidy 建议在所有地方添加 [[nodiscard]]。这是一个好习惯吗?我的理解是 [[nodiscard]] 应该只在忽略 return 值对程序来说可能是致命的时使用。我有一个对象 Car,它有一个成员 const unsigned int m_ID。 getter unsigned int getID() 应该有 [[nodiscard]] 吗? clang-tidy 建议如此。

编辑:

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

的函数

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

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

It should be added where:

  • For existing API’s
    • not using the return value always is a “huge mistake” (e.g. always resulting in resource leak)
    • not using the return value is a source of trouble and easily can happen (not obvious that something is wrong)
  • For new API’s (not been in the C++ standard yet)
    • not using the return value is usually an error.

It should not be added when:

  • For existing API’s
    • not using the return value is a possible/common way of programming at least for some input
      • for example for realloc(), which acts like free when the new site[sic] is 0
    • not using the return value makes no sense but doesn’t hurt and is usually not an error (e.g., because programmers meant to ask for a state change).
    • it is a C function, because their declaration might not be under control of the C++ implementation

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

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

的可能性很大

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

Why clang-tidy suggests to add [[nodiscard]] everywhere?

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

Is this a good practice ?

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

Should the getter unsigned int getID() have [[nodiscard]] ?

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

The understanding I have is that [[nodiscard]] should be used only when ignoring the return value could be fatal for program.

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