如何故意丢弃 \[\[nodiscard\]\] 返回值?

新手上路,请多包涵

说我有

[[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]] 值”?

原文由 spraff 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

WG14 nodiscard 提案 讨论了通过将诊断设置为无效来使诊断静音的基本原理。它说强制转换为 void 是鼓励(如果非规范)使其静音的方法,这遵循现有实现对 __attribute__((warn_unused_result)) 的作用:

[[nodiscard]] 属性具有广泛的实际用途,由 Clang 和 GCC 实现为 attribute((warn_unused_result)) ,但由 WG21 以 [[nodiscard]] 的名称进行标准化。这个提议选择了标识符 nodiscard,因为偏离这个名字会造成与 C++ 的不必要的不兼容。

该属性的语义很大程度上依赖于使用的概念,其定义由实现自行决定。但是, WG21 指定的非规范性指南是鼓励实现在潜在评估的丢弃值表达式中使用 nodiscard 函数调用时发出警告诊断,除非它是显式转换为 void 。这意味着不鼓励实现执行数据流分析(例如需要初始化但未使用的局部变量诊断)。 …

C++ 方式是 static_cast<void>

请参阅 C++ 标准草案 [[ dcl.attr.nodiscard]p2

[ 注意:nodiscard 调用是一个函数调用表达式,它调用先前声明的 nodiscard 函数,或者其返回类型可能是 cv 限定的类或标记为 nodiscard 的枚举类型。 除非显式强制转换为 void,否则不鼓励将 nodiscard 调用作为潜在评估的丢弃值表达式出现。 在这种情况下,实现应该发出警告。这通常是因为丢弃 nodiscard 调用的返回值会产生令人惊讶的后果。 ——尾注]

这是一个注释,因此不规范,但基本上这是现有实现对 __attribute__((warn_unused_result)) 所做的事情。此外,请注意 nodiscard 的诊断也是非规范性的,因此违反 nodiscard 的诊断不是格式错误的,而是执行质量,就像通过强制转换为 void 进行抑制一样。

请参阅 nodiscard 上的 clang 文档 warn_unused_result

Clang 支持诊断在可疑情况下何时丢弃函数调用表达式的结果的能力。当函数或其返回类型被标记为 [[nodiscard]](或 attribute((warn_unused_result)))并且函数调用显示为 未显式强制转换为 void 的潜在评估丢弃值表达式时,将生成诊断。

原文由 Shafik Yaghmour 发布,翻译遵循 CC BY-SA 4.0 许可协议

将其转换为 void

 [[nodiscard]] int foo ()
{
    return 0;
}

int main ()
{
    static_cast<void>(foo());
}

这基本上告诉编译器“ 是的,我知道我正在丢弃它,是的,我很确定。

原文由 Hatted Rooster 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题