G++ How to Get Warning on Ignoring Function Return Value

g++ How to get warning on ignoring function return value

Thanks to WhirlWind and paxdiablo for the answer and comment. Here is my attempt to put the pieces together into a complete (?) answer.

-Wunused-result is the relevant gcc option. And it is turned on by default. Quoting from gcc warning options page:

-Wno-unused-result

Do not warn if a caller of a function marked with attribute warn_unused_result (see
Variable Attributes) does not use its return value. The default is -Wunused-result

So, the solution is to apply the warn_unused_result attribute on the function.

Here is a full example. The contents of the file unused_result.c

int foo() { return 3; }

int bar() __attribute__((warn_unused_result));
int bar() { return 5; }

int main()
{
foo();
bar(); /* line 9 */
return 0;
}

and corresponding compilation result:

$gcc unused_result.c 
unused_result.c: In function ‘main’:
unused_result.c:9: warning: ignoring return value of ‘bar’, declared with attribute warn_unused_result

Note again that it is not necessary to have -Wunused-result since it is default. One may be tempted to explicitly mention it to communicate the intent. Though that is a noble intent, but after analyzing the situation, my choice, however, would be against that. Because, having -Wunused-result in the compile options may generate a false sense of security/satisfaction which is not true unless the all the functions in the code base are qualified with warn_unused_result.

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.
// ...
}

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.

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

How can I enforce an error when a function doesn't have any return in GCC?

GCC has the option -Werror to turn all warnings into errors.

If you want to upgrade only a specific warning, you can use -Werror=X, where X is the warning type, without the -W prefix. In your particular case, that would be -Werror=return-type.

Note that this will only report a missing return in a function that returns a value. If you want to enforce that return; must be explicitly written in a function returning void, you may be out of luck.

How should I handle a value that is never used?

First of all, in case of file handling functions in production-quality code, you should almost certainly handle all return values.

Otherwise, the standard way to ignore a variable or a function result, is to cast it 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.

Why can functions that return values be called without examining the returned value?

You are not obligated to store or examine a value returned from a function if you don't want to.

For example, printf returns an int representing the number of characters successfully written, but most of the time you just call printf to produce output on the screen; you don't care about the return value. For example:

printf("Hello World!\n");

Is a lot more common than:

if(printf("Hello World!\n") != 13)
// printf failed

That said, there are a lot of static analysis tools that can enforce that code that calls certain functions must examine their return values. SAL, which I'm most familiar with, allows you to annotate a function with _Check_return_ or _Must_inspect_result_, and if you then call a function annotated as such without checking its return value, analysis will report a warning.

Example:

_Must_inspect_result_
int foo()
{
return 5;
}

int main(void)
{
foo();
return 0;
}

Running SAL analysis on this code produces the warning message:

C6031 Return value ignored: 'foo'.



Related Topics



Leave a reply



Submit