如何使用GCC属性'format'?

时间:2009-06-15 15:33:20

标签: gcc attributes format warnings printf

这是一小段代码:

#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;
}

我正在使用GCC 4.0编译它,在Mac OS X Leopard上运行Xcode -Wformat和-Wmissing-format-attribute已启用 此代码在第9行(调用vprintf)上发出警告,表明MyPrintf可以使用'format'属性:

  

函数可能是'printf'格式属性的候选者

所以我以这种方式添加属性(不确定这是否正确):

void MyPrintf(char const* format, va_list args) __attribute__((format(printf, 1, 0)));

之前的警告消失,同样的警告现在显示在第16行(致电MyPrintf),表明MyVariadicPrintf可以使用'format'属性。
所以我以这种方式添加属性(这次非常确定这是正确的):

void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2)));

现在我在第22行(​​致电MyVariadicPrintf)收到预期警告:

  

格式

的参数太少
  1. 我做对了吗?
  2. 我注意到在MyPrintf声明中,如果我删除属性部分,我仍然会在第22行得到想要的警告。我还注意到在这个属性部分,将索引从1改为2赢了不要发出任何警告或错误。哪一项是对的,该函数的属性目标是什么?
  3. 如果我添加以下函数MyVariadicPrintfT并调用它(专门用char),我会收到警告,建议在此函数上使用'format'属性。我认为这是不可能的,因为format参数依赖于模板化类型。我是对的吗?

    template<typename Type>
    void MyVariadicPrintfT(Type const* format, ...)
    {
        va_list args;
        va_start(args, format);
        MyPrintf(format, args);
        va_end(args);
    }
    
  4. 最新的gnu文档可以在gnu.org找到 警告选项位于section 3.8(查找“-Wmissing-format-attribute”) 函数属性在section 6.30中(查找“format(archetype,string-index,first-to-check)”)。

    感谢。

2 个答案:

答案 0 :(得分:10)

文档提供了您需要的答案。特别:

  1. 您发布的那个是正确的(format(printf, 1, 0))。 1因为格式字符串是参数1,0,因为没有要检查的可变参数。

答案 1 :(得分:3)

看看GCC docs on gnu.org。至于最后一个问题,我的猜测是MyPrintf不是模板函数,唯一可用的定义将char const*作为第一个参数,因此提出建议感觉很安全。