I was (quickly) writing some code and accidently inverted the arguments in scanf()
:
char i[] = "ABC1\t";
scanf(i, "%s");
Compiling with gcc -Werror -Wall -Wextra
doesn't complain about this one bit. Obviously, this code doesn't work, but why didn't gcc inform me that I inverted the arguments? Can't it detect that i
is not a format string, or that the second argument was not a store-able type?
EDIT
Thanks for the insight all, Looks like I found the answer, there was a twist on the -Wformat
flag that makes this "catchable" (posted it below for reference)
Ha! I found it. Hitting gcc with the -Wformat=2
flag caught it.
Posting the info for reference of others:
Here's the list of flags I found
-Wformat
Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...
I had assumed -Wall
had -Wformat
in it, which it does, but the really important part about what I just found:
-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.
I suppose it shouldn't.
int scanf ( const char * format, ... );
i
was normally converted to a const char*
, all the rest parameters are just "ellipsis" and cannot be checked at compile time.
The manual entry for scanf (man scanf) gives the prototype:
int scanf(const char *format, ...);
A char[] is just a special type of char *, so the first argument is satisfied. Secondary arguments are evaluated at runtime (if I recall), so they aren't even considered by the compiler here. From the compiler's prospective, this is a fine call to the function given its prototype.
Also, the compiler never checks whether you are trying to write to invalid locations. The great (or terrible) thing about C is that it will let you do more or less what you want, even if what you want is a bad idea.