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 的潜在评估丢弃值表达式时,将生成诊断。