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

匿名 (未验证) 提交于 2019-12-03 08:52:47

问题:

#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:

  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



回答8:

You can use

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

to ignore the return value of scanf



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!