如何使用GCC属性“format”?

gc0ot86w  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(188)

下面是一段代码:

#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.我做的对吗?
1.我注意到在MyPrintf声明中,如果我删除属性部分,我仍然会在第22行得到想要的警告。我还注意到,在这个属性部分,将索引从1更改为2不会给予任何警告或错误。哪一个是正确的,这个函数的属性的目标是什么?
1.如果我添加下面的函数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);
 }

最新的gnu文档可以在gnu.org找到。
警告选项位于section 3.8中(查找-Wmissing-format-attribute)。
函数属性在6.30节中(查找 format(archetype,string-index,first-to-check))。

8ljdwjyq

8ljdwjyq1#

文档中有你需要的答案。特别是:
1.是的
1.您所张贴的是正确的(format(printf, 1, 0))。1,因为格式字符串是参数1; 0,因为没有要检查的可变参数。

0ejtzxu1

0ejtzxu12#

看看gnu.org上的GCC文档。至于最后一个问题,我的猜测是MyPrintf不是模板函数,唯一可用的定义将char const*作为第一个参数,所以提出建议是安全的。

相关问题