Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the GCC attribute 'format'?

Here is a little 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

  1. Did I do this right?
  2. 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?
  3. 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)").

Thanks.

like image 886
Guillaume Avatar asked Jun 15 '09 15:06

Guillaume


1 Answers

The documentation has the answer you need. Particularly:

  1. Yes
  2. 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.
like image 53
jpalecek Avatar answered Oct 12 '22 20:10

jpalecek