说我有
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
foo ();
}
然后
error: ignoring return value of ‘int foo()’, declared with attribute nodiscard [-Werror=unused-result]
但如果
int x = foo ();
然后
error: unused variable ‘x’ [-Werror=unused-variable]
是否有一种干净的方法告诉编译器“我想放弃此[[nodiscard]]
值”?
答案 0 :(得分:13)
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
static_cast<void>(foo());
}
这基本上告诉编译器“ 是的,我知道我要丢弃它,是的,我确定。”
答案 1 :(得分:11)
WG14 nodiscard proposal讨论了允许通过强制转换为无效来使诊断静音的理由。它说强制转换为void是一种鼓励(如果不是非规范性的)方法,可以使其静音,该方法遵循现有实现对__attribute__((warn_unused_result))
的作用:
[[nodiscard]]属性在现实世界中有广泛的用途,由Clang和GCC实施为__attribute __((warn_unused_result)) ,但由WG21以[[nodiscard]]的名称进行了标准化。该提案选择了标识符nodiscard 因为偏离此名称会导致与C ++不必要的不兼容。
此属性的语义在很大程度上取决于使用的概念, 定义由实施人员自行决定。然而, WG21指定的非规范性指南旨在鼓励 nodiscard功能时发出警告诊断的实现 在潜在评估的舍弃值表达式中使用call 除非它是明确强制转换为空的。这意味着 不鼓励实现执行数据流分析(例如 需要初始化但未使用的局部变量诊断)。 ...
C ++的方式为static_cast<void>
。
请参阅C ++标准草案[[dcl.attr.nodiscard]p2:
[注:nodiscard调用是一个函数调用表达式,它调用先前声明为nodiscard的函数,或者其返回类型是可能的cv限定类或标记为nodiscard的枚举类型。 不建议将nodiscard调用显示为可能评估的舍弃值表达式,除非明确将其强制转换为void。 在这种情况下,实现应发出警告。 这通常是因为丢弃nodiscard调用的返回值会产生令人惊讶的后果。 —注释]
这是一条注释,因此不是规范性的,但基本上这是现有实现对__attribute__((warn_unused_result))
所做的工作。另外,请注意,对 nodiscard 的诊断也是非规范的,因此,对违反 nodiscard 的诊断不是错误的形式,而是实现质量,就像通过强制转换来抑制一样就是这样。
请参见clang document on nodiscard, warn_unused_result:
Clang支持诊断在可疑情况下何时丢弃函数调用表达式的结果的功能。当函数或其返回类型标记为[[nodiscard]](或__attribute __((warn_unused_result))),并且函数调用显示为可能评估的舍弃表达式(未明确转换)时,将生成诊断。无效。
答案 2 :(得分:8)
您还可以使用另一个标签来标记返回的int
:
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
[[maybe_unused]] int i = foo ();
}
如果您有一些需要该值的仅调试代码,则可能很有用。
答案 3 :(得分:4)
我使用(空的)辅助函数“丢弃”
import shapeless.syntax.singleton._
...
KN(1.narrow)
故意丢弃[[nodiscard]]值。
答案 4 :(得分:2)
#include <boost/core/ignore_unused.hpp>
int main ()
{
boost::ignore_unused(foo ());
}
boost::ignore_unused
通过对 const 的引用来获取其参数,因此该参数必须是您可以绑定到对 const 的引用的东西。我相当确定任何可以是函数返回类型的东西(当然,除了 void!)在这里应该没问题。