How can I intentionally discard a [[nodiscard]] return value?

  • A+
Category:Languages

Say I have

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

then

error: ignoring return value of ‘int foo()’, declared with attribute nodiscard [-Werror=unused-result] 

but if

int x = foo (); 

then

error: unused variable ‘x’ [-Werror=unused-variable] 

Is there a clean way of telling the compiler "I want to discard this [[nodiscard]] value"?

 


The nodiscard proposal discusses this and says casting to void is the encouraged way to silence it which follows what the existing implementation do with __attribute__((warn_unused_result)):

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). e.g.,

#define IGNORE(X)  ((void)X) [[nodiscard]] int foo(void); void func(void) {   foo(); // Diagnose   (void)foo(); // Do not diagnose   IGNORE(foo()); // Do not diagnose   _Generic(foo(), default : 1); // Do not diagnose (foo()                                  // is not evaluated).   int i = foo(); // Do not diagnose, even teven though i is never used. } 

The more C++ way would be static_cast<void> though.

see [[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]

This is a note, so non-normative but basically this is what existing implementations do with __attribute__((warn_unused_result)).

see the 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.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: