我如何故意丢弃 [[nodiscard]] return 值?
How can I intentionally discard a [[nodiscard]] return value?
说我有
[[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]
是否有一种清晰的方式告诉编译器"I want to discard this [[nodiscard]]
value"?
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
static_cast<void>(foo());
}
这基本上告诉编译器“是的,我知道我正在丢弃它,是的,我确定它。”
您还可以用另一个标签标记返回的 int
:
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
[[maybe_unused]] int i = foo ();
}
如果您有一些需要该值的仅调试代码,这可能会很有用。
WG14 nodiscard proposal 讨论了允许通过转换为 void 来使诊断静音的基本原理。它说转换为 void 是鼓励的(如果非规范的)沉默方式,它遵循现有实现对 __attribute__((warn_unused_result))
:
的处理
The [[nodiscard]] attribute has extensive real-world use, being implemented by Clang and GCC as __attribute__((warn_unused_result))
, but was standardized under the name [[nodiscard]] by WG21. This proposal chose the identifier nodiscard
because deviation from this name would create a needless incompatibility with C++.
The semantics of this attribute rely heavily on the notion of a use,
the definition of which is left to implementation discretion. However,
the non-normative guidance specified by WG21 is to encourage
implementations to emit a warning diagnostic when a nodiscard function
call is used in a potentially-evalulated discarded-value expression
unless it is an explicit cast to void. This means that an
implementation is not encouraged to perform dataflow analysis (like an
initialized-but- unused local variable diagnostic would require).
...
C++ 方式是 static_cast<void>
。
参见 C++ 标准草案 [[dcl.attr.nodiscard]p2:
[ Note: A nodiscard call is a function call expression that calls a function previously declared nodiscard, or whose return type is a possibly cv-qualified class or enumeration type marked nodiscard.
Appearance of a nodiscard call as a potentially-evaluated discarded-value expression is discouraged unless explicitly cast to void.
Implementations should issue a warning in such cases.
This is typically because discarding the return value of a nodiscard call has surprising consequences.
— end note]
这是一个注释,因此不规范,但基本上这是现有实现对 __attribute__((warn_unused_result))
的处理方式。另外,请注意 nodiscard 的诊断也是非规范的,因此违反 nodiscard 的诊断不是格式错误,而是实施质量就像通过强制转换为 void 进行压制一样。
查看 clang document on nodiscard, warn_unused_result:
Clang supports the ability to diagnose when the results of a function call expression are discarded under suspicious circumstances. A diagnostic is generated when a function or its return type is marked with [[nodiscard]] (or __attribute__((warn_unused_result))) and the function call appears as a potentially-evaluated discarded-value expression that is not explicitly cast to void.
我使用了一个(空的)辅助函数 "discard"
template<typename T>
void discard(const T&) {}
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
discard(foo());
}
故意丢弃 [[nodiscard]] 值。
#include <boost/core/ignore_unused.hpp>
int main ()
{
boost::ignore_unused(foo ());
}
boost::ignore_unused
通过对 const 的引用获取其参数,因此参数必须是可以绑定到对 const 的引用的内容。我相当确定任何可以是函数 return 类型的东西(当然除了 void!)在这里应该没问题。
CppCoreGuidelines suggest 使用 std::ignore
:
Never cast to (void)
to ignore a [[nodiscard]]
return value. If you deliberately want to discard such a result, first think hard about whether that is really a good idea (there is usually a good reason the author of the function or of the return type used [[nodiscard]]
in the first place). If you still think it's appropriate and your code reviewer agrees, use std::ignore =
to turn off the warning which is simple, portable, and easy to grep.
这与另一个答案中建议的 boost::ignore_unused
几乎相同,但超出了 std::
范围。
但是,使用 std::ignore
有缺点:
- 像其他这样的辅助函数一样,它会实例化,花费编译时间,并被调用(在非优化调试中),花费 运行 时间
std::ignore
适用于 another purpose
std::ignore
甚至不能保证抑制警告
说我有
[[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]
是否有一种清晰的方式告诉编译器"I want to discard this [[nodiscard]]
value"?
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
static_cast<void>(foo());
}
这基本上告诉编译器“是的,我知道我正在丢弃它,是的,我确定它。”
您还可以用另一个标签标记返回的 int
:
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
[[maybe_unused]] int i = foo ();
}
如果您有一些需要该值的仅调试代码,这可能会很有用。
WG14 nodiscard proposal 讨论了允许通过转换为 void 来使诊断静音的基本原理。它说转换为 void 是鼓励的(如果非规范的)沉默方式,它遵循现有实现对 __attribute__((warn_unused_result))
:
The [[nodiscard]] attribute has extensive real-world use, being implemented by Clang and GCC as __attribute__((warn_unused_result)) , but was standardized under the name [[nodiscard]] by WG21. This proposal chose the identifier nodiscard because deviation from this name would create a needless incompatibility with C++.
The semantics of this attribute rely heavily on the notion of a use, the definition of which is left to implementation discretion. However, the non-normative guidance specified by WG21 is to encourage implementations to emit a warning diagnostic when a nodiscard function call is used in a potentially-evalulated discarded-value expression unless it is an explicit cast to void. This means that an implementation is not encouraged to perform dataflow analysis (like an initialized-but- unused local variable diagnostic would require). ...
C++ 方式是 static_cast<void>
。
参见 C++ 标准草案 [[dcl.attr.nodiscard]p2:
[ Note: A nodiscard call is a function call expression that calls a function previously declared nodiscard, or whose return type is a possibly cv-qualified class or enumeration type marked nodiscard. Appearance of a nodiscard call as a potentially-evaluated discarded-value expression is discouraged unless explicitly cast to void. Implementations should issue a warning in such cases. This is typically because discarding the return value of a nodiscard call has surprising consequences. — end note]
这是一个注释,因此不规范,但基本上这是现有实现对 __attribute__((warn_unused_result))
的处理方式。另外,请注意 nodiscard 的诊断也是非规范的,因此违反 nodiscard 的诊断不是格式错误,而是实施质量就像通过强制转换为 void 进行压制一样。
查看 clang document on nodiscard, warn_unused_result:
Clang supports the ability to diagnose when the results of a function call expression are discarded under suspicious circumstances. A diagnostic is generated when a function or its return type is marked with [[nodiscard]] (or __attribute__((warn_unused_result))) and the function call appears as a potentially-evaluated discarded-value expression that is not explicitly cast to void.
我使用了一个(空的)辅助函数 "discard"
template<typename T>
void discard(const T&) {}
[[nodiscard]] int foo ()
{
return 0;
}
int main ()
{
discard(foo());
}
故意丢弃 [[nodiscard]] 值。
#include <boost/core/ignore_unused.hpp>
int main ()
{
boost::ignore_unused(foo ());
}
boost::ignore_unused
通过对 const 的引用获取其参数,因此参数必须是可以绑定到对 const 的引用的内容。我相当确定任何可以是函数 return 类型的东西(当然除了 void!)在这里应该没问题。
CppCoreGuidelines suggest 使用 std::ignore
:
Never cast to
(void)
to ignore a[[nodiscard]]
return value. If you deliberately want to discard such a result, first think hard about whether that is really a good idea (there is usually a good reason the author of the function or of the return type used[[nodiscard]]
in the first place). If you still think it's appropriate and your code reviewer agrees, usestd::ignore =
to turn off the warning which is simple, portable, and easy to grep.
这与另一个答案中建议的 boost::ignore_unused
几乎相同,但超出了 std::
范围。
但是,使用 std::ignore
有缺点:
- 像其他这样的辅助函数一样,它会实例化,花费编译时间,并被调用(在非优化调试中),花费 运行 时间
std::ignore
适用于 another purposestd::ignore
甚至不能保证抑制警告