-Werror=format: how can the compiler know

若如初见. 提交于 2019-12-12 10:49:37

问题


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 and scanf, 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 the printf, scanf, strftime and strfmon (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

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