How to use the GCC attribute 'format'?
attributes, format, gcc, printf, warnings
Solution
The documentation has the answer you need. Particularly:
- Yes
- The one you have posted is correct (`format(printf, 1, 0)`). 1 because the format string is parameter 1, 0 because there are no variadic arguments to be checked.
Problem
Here is a piece of code: ``` #include <stdio.h> #include <stdarg.h> void MyPrintf(char const* format, va_list args); void MyVariadicPrintf(char const* format, ...); void MyPrintf(char const* format, va_list args) { vprintf(format, args); } void MyVariadicPrintf(char const* format, ...) { va_list args; va_start(args, format); MyPrintf(format, args); va_end(args); } int main(int, char*) { MyVariadicPrintf("%s" /* missing 2nd argument */); return 0; } ``` I'm compiling it with GCC 4.0, running Xcode on Mac OS X Leopard. `-Wformat` and `-Wmissing-format-attribute` are enabled. This code gives a warning on line 9 (call to `vprintf`), suggesting that `MyPrintf` could use the 'format' attribute: function might be possible candidate for 'printf' format attribute So I add the attribute this way (not sure if this is right): ``` void MyPrintf(char const* format, va_list args) __attribute__((format(printf, 1, 0))); ``` The previous warning disappears and the same warning now appears on line 16 (call to `MyPrintf`), suggesting that `MyVariadicPrintf` could use the 'format' attribute. So I add the attribute this way (pretty sure this is right this time): ``` void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2))); ``` And now I get the expected warning on line 22 (call to `MyVariadicPrintf`): too few arguments for format Did I do this right? I noticed that on `MyPrintf` declaration, if I delete the attribute part, I'll still get the wanted warning on line 22. I also noticed that in this attribute part, changing the index from 1 to 2 won't give any warning or error. Which one is right and what is the goal of the attribute on this function? If I add the following function `MyVariadicPrintfT` and call it (specialized with `char`), I'll get the warning suggesting to use the 'format' attribute on this function. I think it's impossible because the `format` argument is dependent on the templated type. Am I right? ``` template<typename Type> void MyVariadicPrintfT(Type const* format, ...) { va_list args; va_start(args, format); MyPrintf(format, args); va_end(args); } ``` The latest gnu documentation can be found at gnu.org. Warning Options are in section 3.8 (look for `-Wmissing-format-attribute`). Function Attributes are in section 6.30 (look for format (archetype, string-index, first-to-check)).