可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
#include 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?
回答1:
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 int main() { int t; if (scanf("%d", &t) == 1) { printf("%d", t); } else { printf("Failed to read integer.\n"); } return 0; }
回答2:
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);
回答3:
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
回答4:
Do this:
int main() { int t; int unused __attribute__((unused)); unused = scanf("%d",&t); printf("%d",t); return 0; }
回答5:
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 #include #include void inline 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
回答6:
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.
回答7:
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 your gcc
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
回答8:
You can use
(void) scanf("%d",&t);
to ignore the return value of scanf