32

lint produces some warning like:

foo.c XXX Warning 534: Ignoring return value of function bar()

From the lint manual

534 Ignoring return value of function

'Symbol' (compare with Location) A function that returns a value is called just for side effects as, for example, in a statement by itself or the left-hand side of a comma operator. Try: (void) function(); to call a function and ignore its return value. See also the fvr, fvo and fdr flags in §5.5 "Flag Options".

I want to get this warning, if there exists any, during compilation. Is there any option in gcc/g++ to achieve this? I had turned on -Wall but that apparently did not detect this.

iammilind
  • 68,093
  • 33
  • 169
  • 336
Arun
  • 19,750
  • 10
  • 51
  • 60

5 Answers5

33

Since C++17 you can use the [[nodiscard]] attribute.

Example:

[[nodiscard]] int bar() {
  return 42;
}
Jyaif
  • 1,047
  • 1
  • 10
  • 17
  • 1
    Perhaps it is worth mentioning that this only means that the compiler is [encouraged to issue a warning](http://en.cppreference.com/w/cpp/language/attributes) (no guarantee) – ricab Apr 08 '18 at 16:26
  • 2
    And in C++20 you can add message string: https://en.cppreference.com/w/cpp/language/attributes/nodiscard – Ciro Santilli OurBigBook.com May 08 '20 at 08:44
30

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.

Community
  • 1
  • 1
Arun
  • 19,750
  • 10
  • 51
  • 60
  • 1
    if `-Wunused-result` is the default, how come the compiler (gcc 9.2.1) is not warning me about ignoring `fgets` return value? one of the most important purposes of `fgets` is to precisely return a byte from the stream, so ignoring it could be a big deal. – m4l490n Feb 13 '20 at 14:56
  • 1
    @m4l490n Maybe `fgets` is not _"marked with attribute `warn_unused_result`"_ (and maybe it should be)? – nh2 Aug 08 '20 at 00:44
9

-Wunused-result should do this for you. This isn't one of the warnings -Wall turns on:

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

The function has to have the warn_unused_result attribute applied to it (Thanks paxdiablo).

WhirlWind
  • 13,974
  • 3
  • 42
  • 42
8

The answers about using __attribute__((warn_unused_result)) are correct. GCC isn't so good at this functionality, though! Be aware: it will not warn for non-POD types. That means, for example, if you return a class with a destructor (or a class with instance variables with destructors) you'll never see a warning about ignoring the result.

Relevant bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66177

Example where it fails:

struct Error {
~Error();
};

__attribute__((warn_unused_result)) Error test();

int main()
{
    test();
    return 0;
}

So, don't rely on this for return types which aren't pretty simple.

Jonah
  • 146
  • 2
  • 4
  • 1
    some additional relevant bugzillas: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38172 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46643 – pestophagous Jul 19 '17 at 20:58
-3

I solved the problem like this:

#define ignore_result(x) if (x) {}

then instead of (void)foo() use ignore_result(foo())

Then the code compiles with -Wall just fine.

Sasha Pachev
  • 5,162
  • 3
  • 20
  • 20