Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result

C

C Problem Overview


#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    printf("%d", t);
    return 0;
}

I compiled the above C code using ideone.com and the following warning popped up:

> prog.c: In function ‘main’:
> prog.c:5: warning: ignoring return value > of ‘scanf’, declared with attribute warn_unused_result

Can someone help me understand this warning?

C Solutions


Solution 1 - C

The writer's of your libc have decided that the return value of scanf should not be ignored in most cases, so they have given it an attribute telling the compiler to give you a warning.

If the return value is truly not needed, then you are fine. However, it is usually best to check it to make sure you actually successfully read what you think you did.

In your case, the code could be written like this to avoid the warning (and some input errors):

#include <stdio.h>

int main() {
    int t;
    if (scanf("%d", &t) == 1) {
        printf("%d", t);
    } else {
        printf("Failed to read integer.\n");
    }
    return 0;
}

Solution 2 - C

The warning (rightly) indicates that it is a bad idea not to check the return value of scanf. The function scanf has been explicitly declared (via a gcc function attribute) to trigger this warning if you discard its return value.

If you really want to forget about this return value, while keeping the compiler (and your conscience) happy, you can cast the return value to void:

(void)scanf("%d",&t);

Solution 3 - C

I tried your example with gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3. The warning is issued if and only if optimizing, e.g., with option -O2 or -O3. Requesting all warnings (-Wall) doesn't matter. The classic idiom of casting to void has no effect, it does not suppress the warning.

I can silence the warning by writing

if(scanf("%d",&t)){};

this works, but it's a bit obscure for my taste. Empty {} avoids yet another warning -Wempty-body

Solution 4 - C

Do this:

int main() {
    int t;
    int unused __attribute__((unused));
    unused = scanf("%d",&t);
    printf("%d",t);
    return 0;
}

Solution 5 - C

After reading all answers and comments on this page I don't see these yet another options to avoid the warning:

When compiling with gcc you can add to your command line:

> gcc -Wall -Wextra -Wno-unused-result proc.c -o prog.x

Another option is to use -O0 as "optimization level zero" ignores the warning.

Using cast to (void) is simply useless when compiling with gcc

If debugging your code, you can always use assert() as in the example bellow:

u = scanf("%d", &t);
assert(u == 1);

But now, if you turn off assert via #define NDEBUG you will get a -Wunused-but-set-variable. You can then turn off this second warning by one of two ways:

  1. Adding -Wno-unused-but-set-variable to your gcc command line, or
  2. Declaring the variable with attribute: int u __attribute__((unused));

As pointed out in other answer, the second option unfortunately is not very portable, although it seems the best option.

At last, the defined MACRO bellow can help you if you are sure you want to ignore the return of a given function, but you are not comfortable turning off the warnings for all unused returns of functions:

#define igr(x) {__typeof__(x) __attribute__((unused)) d=(x);} 

double __attribute__ ((warn_unused_result)) fa(void) {return 2.2;}
igr(fa());

See also this answer

Solution 6 - C

One way to solve this is the IGUR() function as seen below. Extremely ugly, but nevertheless somewhat portable. (For old compilers which do not understand inline just #define inline /*nothing*/, as usual.)

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

inline void IGUR() {}  /* Ignore GCC Unused Result */
void IGUR();  /* see https://stackoverflow.com/a/16245669/490291 */

int
main(int argc, char **argv)
{
  char	buf[10*BUFSIZ];
  int	got, fl, have;

  fl	= fcntl(0, F_GETFL);
  fcntl(0, F_SETFL, fl|O_NONBLOCK);
  have = 0;
  while ((got=read(0, buf, sizeof buf))>0)
    {
      IGUR(write(1, buf, got));
      have = 1;
    }
  fcntl(0, F_SETFL, fl);
  return have;
}

BTW this example, nonblockingly, copies from stdin to stdout until all waiting input was read, returning true (0) if nothing was there, else false (1). (It prevents the 1s delay in something like while read -t1 away; do :; done in bash.)

Compiles without warning under -Wall (Debian Jessie).

Edit: IGUR() needs to be defined without inline, too, such that it becomes available for the linker. Else with cc -O0 it might fail. See: https://stackoverflow.com/a/16245669/490291

Edit2: Newer gcc require inline to be before void.

Solution 7 - C

Actually it depends on what you need, if you just want to disable the warning of compiler, you can just ignore the return value of the function by the force conversion or you can just handle it, the meaning of the scanf function is the count of user input.

==== update ====

You can use

(void) scanf("%d",&t);

to ignore the return value of scanf

Solution 8 - C

> Can someone help me understand this warning?

No, but here is my contribution to the horror of warning suppression. To actively throw the return value out the window, elegance dictates wrapping our statement in a comprehensible lambda function, like this:

[&]{ return scanf("%d", &t); }();

My apologies.

Solution 9 - C

scanf, printf is functions that returns value, usually in those kind of functions it's the amount of characters read or written. if an error occurs, you can catch the error also with the return code. A good programming practice will be to look at the return value, however, I never saw someone who looks at the printf return value...

If you want the warning to disappear, you can probably change the severity of the compiler.

Solution 10 - C

Since functions without arguments are valid in C, you can do the following:

#include <stdio.h>

static inline void ignore_ret() {}

int main() {
   int t;
   ignore_ret(scanf("%d", &t));
   return 0;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvipinView Question on Stackoverflow
Solution 1 - CEvan TeranView Answer on Stackoverflow
Solution 2 - CAlexandre C.View Answer on Stackoverflow
Solution 3 - CQuigiView Answer on Stackoverflow
Solution 4 - CWaxratView Answer on Stackoverflow
Solution 5 - CDrBecoView Answer on Stackoverflow
Solution 6 - CTinoView Answer on Stackoverflow
Solution 7 - CActonView Answer on Stackoverflow
Solution 8 - C魔大农View Answer on Stackoverflow
Solution 9 - CstdcallView Answer on Stackoverflow
Solution 10 - CJari VetoniemiView Answer on Stackoverflow