Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result
CC 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:
- Adding
-Wno-unused-but-set-variable
to yourgcc
command line, or - 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;
}