How do I ignore the gets() warning when compiling? - c

I know you quickly clicked this expecting to answer NEVER USE GETS! but I have a valid reason. I am learning about buffer overflows and need to purposely develop vulnerable software.
So, as the title states, how do I ignore the warnings so the compilation succeeds? I have tried:
gcc bo.c -o bo -Wall
... to no avail.
Thanks for any help.

This code:
#include <stdio.h>
int main() {
char foo[10];
gets( foo );
return 0;
}
produces the following output when compiled:
bo.c: In function 'main':
bo.c:4:2: warning: 'gets' is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations]
gets( foo );
^
/tmp/cclk8TkP.o: In function `main':
bo.c:(.text+0x10): warning: the `gets' function is dangerous and should not be used.
The first warning is from the compiler, and we can see what flag to use to suppress it: -Wno-deprecated-declarations.
This leaves the second warning, which is from the linker. As far as I can tell there is no way to suppress that warning easily (see here and here). However it should not be a problem, since it is a warning, not an error; the executable gets created.

use fgets instead of gets
Example:
fgets (foo, sizeof(foo), stdin);

Related

How should I handle a value that is never used?

I don't always use all return values, and sometimes I must handle return values. For instance:
$ make
gcc -pedantic -std=c99 -Wall -O3 -ledit -g -DVERSION=\"v0.160425-2-gc443\" -c -o main.o main.c
main.c: In function ‘int_handler’:
main.c:532:5: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result]
write(fileno(stdin), s, sizeof s - 1);
^
gcc -o shell main.o errors.c util.c pipeline.c -ledit
What should I do to avoid the warning? Is there a good way to "use" a variable like writing it to /dev/null so that the compiler won't complain? My own idea is this, which deals with the problem without ignoring the error and I can commit my code without warnings and deal with this later:
void int_handler(int signum) {
if (write(fileno(stdin), s, sizeof s - 1)) {
} else {}
}
Typically to suppress this warning, you can do:
(void)write(fileno(stdin), s, sizeof s - 1);
But the reason for the warning is because write() is declared with an attribute in the header (<unistd.h>) which leads to the warning.
This (attribute) is not done for every function but selectively. For example, printf()'s return is typically ignored.
Since, you would want to check the results of IO operation, it's done for write().
So, if you really want to ignore the result, you can use the (void)func(...); to suppress this.
First of all, in case of file handling functions in production-quality code, you should almost certainly handle all return values.
Otherwise, the standard way to ignore a variable or a function result, is to cast it to (void).
It is a bad idea to not take in account the return value of a call to write, as an I/O may fail it is important to take care of such an event. If you really want to remove the warning, you should explicitly ignore the return value:
(void)write(...);
The prototype for write in the header file unistd.h has been declared as follows
extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
and __wur has been defined as (in cdefs.h)
# if __USE_FORTIFY_LEVEL > 0
# define __wur __attribute_warn_unused_result__
# endif
#else
# define __attribute_warn_unused_result__ /* empty */
So when you are compiling with fortify switch on, wur gets defined as
__attribute_warn_unused_result. This attribute essentially tells the compiler to throw out warning if return value of function is not used.
You can redirect your stdout and stderr to /dev/null
gcc -c file.c > /dev/null 2>&1
and get rid of the warning (though even error is redirected to null) or you can redirect to file as
gcc -c warn.c > xx 2>&1
Hope this helps . And like said above, always check the value of "write", the error will automatically vanish
:)

Why do I get "Invalid conversion from "void *" to "int**" error?

my code shows this warnings when compiling with "g++ -Wall -pedantic -Wno-long-long -c main.c". I have to compile in this mode, becouse its a homework and we have an application that corrects them and it uses this compile mode.
Error: invalid conversion from "void" to "int** " [-fpermissive]
Error: invalid conversion from "void" to "int* " [-fpermissive]
Error: invalid conversion from "void" to "main(int, char*)::VYSLEDEK" [-fpermissive]
the same errors continue as i realloc quite a lot in my program. I tried to change almost everything in that realloc, it is still the same.
Parts of the code :
struct VYSLEDEK
{
int sirka;
int vyska;
int zacatek_x;
int zacatek_y;
int soucet;
} *vysledek;
int **matice,**soucty;
.....
matice=(int**)malloc(1*sizeof(int*));
matice[0]=(int*)malloc(1*sizeof(int));
soucty=(int**)malloc(1*sizeof(int*));
soucty[0]=(int*)malloc(1*sizeof(int));
.....
1. matice=realloc(matice,naalokovano*2*sizeof(int*));
2. soucty=realloc(soucty,naalokovano*2*sizeof(int*));
.....
for (i=0;i<(naalokovano*2);i++)
{
3. matice[i]=realloc(matice[i],sizeof(int));
4. soucty[i]=realloc(soucty[i],sizeof(int*));
};
.....
5. vysledek=realloc(vysledek,vysledku*sizeof(struct VYSLEDEK*));
Thank you for your help.
You already did cast the result of malloc to the right type. Do the same for the realloc calls, too.
BTW: Don’t complain that they force you to switch on the warnings. I think it’s the most sensible thing to do by default, I always use at least -Wall -Werror.

Disable warning/error for default warnings

We want to start using -Wall -Werror on a large project.
Due to the size, this change has to be phased, and we want to start with the most important warnings first.
The best way to do it seems to be using -Wall -Werror, with exceptions for specific warnings. The exceptional warnings are those which we have a lot of (so fixing them all is hard and risky), and we don't consider them very dangerous.
I'm not saying we don't want to fix all these warnings - just not on the first phase.
I know two ways to exclude a warning from -Werror - the best is -Wno-error=xxx, and if it doesn't work - -Wno-xxx (of course, we prefer to see the warning and ignore it, rather than hide it).
My problem is with warnings which are enabled by default, and don't have a -Wxxx flag related to them. I couldn't find any way to alllow them when -Werror is used.
I'm specifically concerned about two specific warnings. Here's a program that exhibits them and the compiler output:
#include <stdio.h>
void f(int *p) { printf("%p\n", p); }
int main(int argc, char *argv[]) {
const int *p = NULL;
const unsigned int *q = NULL;
f(p); /* Line 7: p is const, f expects non const */
if (p == q) { /* Line 8: p is signed, q is unsigned */
printf("Both NULL\n");
}
return 0;
}
% gcc warn.c
warn.c: In function 'main':
warn.c:7: warning: passing argument 1 of 'f' discards qualifiers from pointer target type
warn.c:8: warning: comparison of distinct pointer types lacks a cast
I know the best solution is to fix these warnings, but it's much easier said than done. In order for this change to be successful, we have to do this phased, and can't do too many changes at once.
Any suggestions?
Thanks.
What about phasing on a compilation unit/module/library basis instead of per warning? Is triggering a subtarget compilation an option (a good-enough build system in place)?
It might be folly, but ...
Why not a simple grep ?
something like
gcc teste.c 2>&1 | grep -v 'comparison of distinct' | grep -v 'some_other_string'
You probably want to hide these greps in a script, and call the script from your makefile instead of gcc
According to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43245 it will be "-Wdiscarded-qualifiers", but since the bug-fixed entry is from May 1, 2014, the gcc compiler you are using might not support it.

How do I remove the following 'implicit declaration of function' warnings?

How do I compile the lex file with gcc without receiving the following warnings?
lex.yy.c: In function `yy_init_buffer':
lex.yy.c:1688: warning: implicit declaration of function `fileno'
lex.l: In function `storeLexeme':
lex.l:134: warning: implicit declaration of function `strdup'
These are the libraries I included.
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
%}
The function yy_init_buffer is not in the file. The following is the function storeLexeme.
int storeLexeme() {
for (int i = 0; i < count; i++) {
char *curr = *(symbolTable + i);
if (strcmp(curr, yytext) == 0) {
return i;
}
}
char *lexeme = (char *)malloc(sizeof(char *));
lexeme = (char *)strdup(yytext);
symbolTable[count] = lexeme;
count++;
return (count - 1);
}
How do I remove the warnings?
Neither strdup nor fileno are ISO C functions, they're part of POSIX.
Now whether they're available on your platform depends on your platform.
If you are using the Microsoft tools, you may want to look into _fileno for the latter (fileno was deprecated in VC2005). A rather excellent version of strdup can be found here.
Although, having blown my own horn with that code, you could also use _strdup since it replaces the also-deprecated strdup :-)
These should hopefully work okay as-is since they're in stdio.h and string.h, two of the include files you're already using.
If you're on a UNIX derivative, those functions should be available in stdio.h (for fileno) and string.h (for strdup). Given that it looks like you're already including those files, the problem is likely elsewhere.
One possibility is if you're compiling in one of the strict modes like __STRICT_ANSI__ in gcc), where neither would be defined.
You should have a look at the top of your generated lex.yy.c and lex.l files to confirm that the header files are being included and also check the command line parameters you're passing to the compiler.
I suggest this option (tell the compiler you are using POSIX):
#define _POSIX_C_SOURCE 1
People seem to have tightened up the feature controls in recent years and hopefully when the consistency is good and widespread we can throw away the automake garbage.
I also had this problem while using flex.
I used -std=gnu99rather than -std=c99 which solved the problem.
flex lang.l && gcc -o lexer -std=gnu99 lex.yy.c -lfl
Consider adding the following line:
extern char *strdup(const char *s);
I faced the problem when I compiled with -std=c99 -pedantic -pedantic-errors. Adding the above line solved the problem for me.
You declare the function before you use it:
//declare the function
int storeLexeme();
//use the function here
or include the header where the function is declared.
C implicitly assumes undeclared functions have return type int and deduces the parameters from how you call the function. This is deprecated in C++.
just place your function below the library calls it will be alright;

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

#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;
}

Resources