How to Raise Warning If Return Value Is Disregarded

How to raise warning if return value is disregarded?

You want GCC's warn_unused_result attribute:

#define WARN_UNUSED __attribute__((warn_unused_result))

int WARN_UNUSED f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}

int main()
{
int i = 7;
f(i); ///// <<----- here i disregard the return value
return 1;
}

Trying to compile this code produces:

$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result

You can see this in use in the Linux kernel; they have a __must_check macro that does the same thing; looks like you need GCC 3.4 or greater for this to work. Then you will find that macro used in kernel header files:

unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);

How to resolve warning ignoring return value of function declared with 'warn_unused_result' attribute

Issue is not with lambda, but your usage:

You should use/check return value of qWaitFor (to know if timeout happens):

if (QTest::qWaitFor([tabs, ¤tIdx]() {
currentIdx = tabs->currentIndex();
return currentIdx == 1;
}, 5000)) {
// OK.
// ...
} else {
// timeout.
// ...
}

How to enforce the usage of return values in C

I never used it myself (do you really need it?), you can try

  • defining the function with warn_unused_result attribute
  • enabling -Wunused-result flag with gcc.

This will tell you about any unused value from the function return.


In case, any doubts, SEE IT LIVE or SEE IT LIVE AGAIN Thanks to M.M for the link in the comment

Or:

#include <stdio.h>

extern int func1(void) __attribute__((warn_unused_result));
extern int func2(void);

int main(void)
{
func1();
int rc1 = func1();
int rc2 = func1();
func2();
printf("%d\n", rc1);
return 0;
}

Compilation (GCC 5.1.0 on Mac OS X 10.10.5):

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c warn.c
warn.c: In function ‘main’:
warn.c:10:9: error: unused variable ‘rc2’ [-Werror=unused-variable]
int rc2 = func1();
^
warn.c:8:5: error: ignoring return value of ‘func1’, declared with attribute warn_unused_result [-Werror=unused-result]
func1();
^
cc1: all warnings being treated as errors
$

GCC: warning on unused return

// header
int test ( int a ) __attribute__ ((warn_unused_result));

// function
int test ( int a )
{

if ( a<0 ) return 1;

return 0;
}

// main program
int main ( void )
{

int a = -10;

test(a);

return 0;
}

It should work now.

Can a C++ function be declared such that the return value cannot be ignored?

To summarize from other answers & comments, basically you have 3 choices:

  1. Get C++17 to be able to use [[nodiscard]]
  2. In g++ (also clang++), use compiler extensions like __wur (defined
    as __attribute__ ((__warn_unused_result__))), or the more portable (C++11 and up only) [[gnu::warn_unused_result]] attribute.
  3. Use runtime checks to catch the problem during unit testing

If all of these 3 are not possible, then there is one more way, which is kind of "Negative compiling". Define your Unignorable as below:

struct Unignorable {
Unignorable () = default;
#ifdef NEGATIVE_COMPILE
Unignorable (const Unignorable&) = delete; // C++11
Unignorable& operator= (const Unignorable&) = delete;
//private: Unignorable (const Unignorable&); public: // C++03
//private: Unignorable& operator= (const Unignorable&); public: // C++03
/* similar thing for move-constructor if needed */
#endif
};

Now compile with -DNEGATIVE_COMPILE or equivalent in other compilers like MSVC. It will give errors at wherever the result is Not ignored:

auto x = foo();  // error

However, it will not give any error wherever the result is ignored:

foo(); // no error

Using any modern code browser (like eclipse-cdt), you may find all the occurrences of foo() and fix those places which didn't give error. In the new compilation, simply remove the pre-defined macro for "NEGATIVE_COMPILE".

This might be bit better compared to simply finding foo() and checking for its return, because there might be many functions like foo() where you may not want to ignore the return value.

This is bit tedious, but will work for all the versions of C++ with all the compilers.

Ignoring return values in C

The common way is to just call foo(); without casting into (void).

He who has never ignored printf()'s return value, cast the first stone.

How to raise warning if return value is disregarded?

You want GCC's warn_unused_result attribute:

#define WARN_UNUSED __attribute__((warn_unused_result))

int WARN_UNUSED f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}

int main()
{
int i = 7;
f(i); ///// <<----- here i disregard the return value
return 1;
}

Trying to compile this code produces:

$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result

You can see this in use in the Linux kernel; they have a __must_check macro that does the same thing; looks like you need GCC 3.4 or greater for this to work. Then you will find that macro used in kernel header files:

unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);

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

The WG14 nodiscard proposal discusses the rationale for allowing the diagnostic to be silenced by casting to void. It says casting to void is the encouraged (if non-normative) way to silence it which follows what the existing implementation do with __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).
...

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

See the draft C++ standard [[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)). Also, note a diagnostic for nodiscard is also also non-normative, so a diagnostic for violating nodiscard is not ill-formed but a quality of implementation just like suppressing via a cast to void is.

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.

Why cast unused return values to void?

David's answer pretty much covers the motivation for this, to explicitly show other "developers" that you know this function returns but you're explicitly ignoring it.

This is a way to ensure that where necessary error codes are always handled.

I think for C++ this is probably the only place that I prefer to use C-style casts too, since using the full static cast notation just feels like overkill here. Finally, if you're reviewing a coding standard or writing one, then it's also a good idea to explicitly state that calls to overloaded operators (not using function call notation) should be exempt from this too:

class A {};
A operator+(A const &, A const &);

int main () {
A a;
a + a; // Not a problem
(void)operator+(a,a); // Using function call notation - so add the cast.

ignoring warning -Wunused-result

If the return value of a function is to ignored, then one portable-ish way is to mark it with void as:

  (void) frepoen("input", "r", stdin);

It is a clear indication to both the reader as well as the compiler that the return value is really not necessary.

However, if a file is re-opened (freopen), then isn't the return value (FILE *) necessary for subsequent read/write operations on the file?

As Striezel pointed out, for stdin and stdout, althught the return value is not necessary for subsequent file operation, it may still be necessary for error checking. Upon failure, freopen returns NULL.



Related Topics



Leave a reply



Submit