7

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?

XPlatformer
  • 1,148
  • 8
  • 18
  • "because the format string isn't parsed until runtime" are you sure? That's interesting, if it's true. Doesn't make sense to me to be left for runtime. – Kiril Kirov Dec 06 '13 at 13:06
  • 5
    The compiler does no magic code analysis. It has special case checking for `printf` and similar `libc` functions. It will not automatically work with your own functions. – Jesper Dec 06 '13 at 13:06

2 Answers2

11

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.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • this `__attibute__` is very usefull. Do Clang and MSVC++ have somthing similar? – XPlatformer Dec 06 '13 at 13:39
  • 1
    @user3001464: Clang has the same attribute as GCC. I never use Microsoft's compiler, but [this question](http://stackoverflow.com/questions/2354784) seems to indicate that there's something similar. – Mike Seymour Dec 06 '13 at 13:42
6

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.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • Concerning leveraging this functionality for your own functions: you can and you can't. You can specify the `format` attribute for your own functions, but you must specify which of the standard format strings it uses; you can't invent something totally new. – James Kanze Dec 06 '13 at 13:15
  • @JamesKanze: Thanks, I was not aware of that. – Jon Dec 06 '13 at 13:25