问题
I wrote this intentionally wrong code
printf("%d %d", 1);
compiling with g++
and -Werror=format
.
The compiler gives this very impressive warning:
error: format '%d' expects a matching 'int' argument [-Werror=format]
As far as I can see, there's no way the compiler can tell that the code is wrong, because the format string isn't parsed until runtime.
My question: does the compiler have a special feature that kicks in for printf and similar libc functions, or is this a feature I could use for my own functions? String literals?
回答1:
As far as I can see, there's no way the compiler can tell that the code is wrong, because the format string isn't parsed until runtime.
As long as the format string is a string literal, it can be parsed at compile time. If it isn't (which is usually a bad idea anyway), then you can get a warning about that from -Wformat-security
.
does the compiler have a special feature that kicks in for printf and similar libc functions?
Yes.
or is this a feature I could use for my own functions?
Yes, as long as you're using the same style of format string as printf
(or various other standard functions like scanf
or strftime
).
void my_printf(Something, char const * format, SomethingElse, ...)
__attribute__ ((format (printf,2,4)));
to indicate that the second argument is a printf
-style format string, and the values to format begin with the fourth. See http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html.
回答2:
Well, printf
definitely parses the format string at runtime in order to do its job. But nowhere is it written that the compiler may not choose to parse it itself if it wants to.
The documentation for -Wformat
says that this is exactly what happens:
-Wformat
-Wformat=n
Check calls to
printf
andscanf
, etc., to make sure that the arguments supplied have > types appropriate to the format string specified, and that the conversions specified in the format string make sense. This includes standard functions, and others specified by format attributes (see Function Attributes), in theprintf
,scanf
,strftime
andstrfmon
(an X/Open extension, not in the C standard) families (or other target-specific families). Which functions are checked without format attributes having been specified depends on the standard version selected, and such checks of functions without the attribute specified are disabled by-ffreestanding
or-fno-builtin
.The formats are checked against the format features supported by GNU libc version 2.2. These include all ISO C90 and C99 features, as well as features from the Single Unix Specification and some BSD and GNU extensions. Other library implementations may not support all these features; GCC does not support warning about features that go beyond a particular library's limitations. However, if -Wpedantic is used with -Wformat, warnings are given about format features not in the selected standard version (but not for strfmon formats, since those are not in any version of the C standard). See Options Controlling C Dialect.
Update: Turns out you can use it on your own functions. Mike has the details.
来源:https://stackoverflow.com/questions/20424625/werror-format-how-can-the-compiler-know