This question already has answers here:
How to raise warning if return value is disregarded?
(8 answers)
Closed 7 years ago.
Problem statement
I use a return integer to propagate errors through my code. I would like gcc to provide me with a warning if I accidentally forget to propagate the error (i.e. when I forget to use the return integer).
Example
Consider this very simple example test.c:
// header
int test ( int a );
// function
int test ( int a )
{
if ( a<0 ) return 1;
return 0;
}
// main program
int main ( void )
{
int a = -10;
test(a);
return 0;
}
Expected behavior
$ gcc -Wunused-result main.c
Warning: main.c:19 ... unused return ...
or alternatively using Wall or Wextra or another option.
Needless to say, my compiler does not provide the warning with any of these options. One of my mistakes already took me frustratingly long to find...
// header
int test ( int a ) __attribute__ ((warn_unused_result));
// function
int test ( int a )
{
if ( a<0 ) return 1;
return 0;
}
// main program
int main ( void )
{
int a = -10;
test(a);
return 0;
}
It should work now.
In gcc and clang, you can mark specific functions with the warn_unused_result attribute and it will let you know if you ignore the result (assuming you're not using the -Wno-unused-result flag, of course).
Unfortunately, I'm not aware of a way to get those compilers to apply this to all functions globally, you have to do it explicitly on a case-by-case basis.
In any case, doing it globally would cause some rather annoying behaviour from things like printf where you may not care about the return code.
Related
#include<stdio.h>
int cube(int n)
{
return (n*n*n);
}/*function to return cubic root*/
int sumcube(int x)
{
int sum=0,m;
while(x>0)
{
m=x%10;
sum=sum+(cube(m));
x=x/10;
}
return sum;
}/* returns the sum if cubic digits of an integer*/
int main ()
{
int i;
for(i=1; i<=5000; i++)
{
if (i==sumcube(i));
{
printf("%d\t",i);
}
}
}
/* this program is to check wether a number is an armestrong from 1 to 5000 as well as to check the output was all the integers from 1 to 5000*/
You have a ; after the if, this is interpreted as an empty body for the if and therefore everything after it will be executed regardless if the condition in the if-statement is true or not.
To avoid the same error in the future, enable all compiler warnings and only disable the warnings you are sure you want to ignore and set the treat warnings as error flag for development (not when you release code, but that is not something you should do at your knowledge level). For gcc use the flags -Wall -Wextra -Wpedantic -Werror. With that, the compiler generates an error for your code.
I have a problem described in the title. I have an Edify language parser that runs without errors when I building it on arm but fails when I try to use it with x86. I traced segfault to yy_scan_bytes function, more precisely to this code:
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) {
YY_BUFFER_STATE b;
char * buf;
yy_size_t n;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
buf = (char *) yyalloc(n );
if ( ! buf ) {
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
}
for ( i = 0; i < _yybytes_len; ++i ) {
buf[i] = yybytes[i]; // <==========
}
The full code is here: https://github.com/twaik/edify_x86_failing_code
I've got it from AROMA Installer source.
That's everything I discovered after debug. Thanks.
Trying to build your code gives me these errors:
main.c: In function ‘parse_string’:
main.c:27:5: warning: implicit declaration of function ‘yy_switch_to_buffer’ [-W
implicit-function-declaration]
yy_switch_to_buffer(yy_scan_string(str));
^~~~~~~~~~~~~~~~~~~
main.c:27:25: warning: implicit declaration of function ‘yy_scan_string’ [-Wimplicit-function-declaration]
yy_switch_to_buffer(yy_scan_string(str));
That means that the compiler assumes that yy_switch_to_buffer() and yy_scan_string() return an int, as it does for all functions that are not declared before use (as per the c89 standard). But that is not the case (the first returns void, and the second a pointer (YY_BUFFER_STATE)). Notice that on x86_64, the size of a pointer is not the same as the size of an int.
Adding some band-aid prototypes like
void yy_switch_to_buffer(void*);
void *yy_scan_string(const char*);
to main.c, before their use in parse_string() may stop the segfaulting.
A better fix would be to arrange in the Makefile that the lexer be run with the --header-file=lex-header.h option, and then include lex-header.h from main.c. Or even better, wrap all lex-specific code in some simple functions, and put the prototypes of those functions in a header included from both main.c and the *.l file.
#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?
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;
}
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);
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
Do this:
int main() {
int t;
int unused __attribute__((unused));
unused = scanf("%d",&t);
printf("%d",t);
return 0;
}
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
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.
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
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.
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.
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;
}
just use a surrunding if () and an empty block, the terminating semikolon has to be in the next line (to prevent additional warnings)
#include <stdio.h>
main (int argc, char const *argv[]) {
...
if ( scanf("%d",&n) )
;
...
return 0;
}
I have a problem using sqrt() in c.
I'm trying to do something like this:
int a;
a = sqrt(9);
etc
I'm restricted to use:
gcc -ansi -Wall -pedantic oneFile.c anotherFile.c thirdFile.c -o outputFileName
How can I make this compile without using the -lm command?
Yes, I have #include !
Is there any way around this and still use sqrt()?
Thanks
You can't make it compile without -lm. That's an instruction to the linker to compile against the built-in math library. It isn't enough to say #include <math.h>, because that's only a header file - there's no code in there, that simply tells the compiler what the functions you're using look like. You still need to actually get the implementation of that function into your code, and -lm basically tells the linker look in libm, check to see if it has any functions that we haven't found yet. If you don't look in there, you'll never be able to actually execute sqrt because the code simply isn't in your program.
If you're working on a homework assignment and are restricted to using that command line, then it's possible that part of your assignment is to not use anything from the math library, and so you may be expected to consider an alternate approach.
just try with this function, If you don`t want to use library.
Sq_root(n)
{
count=0;
int i = 0;
for(i=1;sum<=n;i+=2)
{
sum+=i;
count++;
}
return (count);
}
This will work, without any math library.
use #include <math.h> in header
else use user define function
int int_sqrt(int x){
int s, t;
s = 1; t = x;
while (s < t) {
s <<= 1;
t >>= 1;
}
do {
t = s;
s = (x / s + s) >> 1;
} while (s < t);
return t;
}
#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?
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;
}
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);
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
Do this:
int main() {
int t;
int unused __attribute__((unused));
unused = scanf("%d",&t);
printf("%d",t);
return 0;
}
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
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.
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
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.
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.
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;
}
just use a surrunding if () and an empty block, the terminating semikolon has to be in the next line (to prevent additional warnings)
#include <stdio.h>
main (int argc, char const *argv[]) {
...
if ( scanf("%d",&n) )
;
...
return 0;
}