这是一小段代码:
#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
可以使用“格式”属性:
函数可能是“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
):
格式参数太少
- 我做对了吗?
- 我注意到在
MyPrintf
声明时,如果我删除属性部分,我仍然会在第 22 行得到想要的警告。我还注意到,在这个属性部分中,将索引从 1 更改为 2 不会给出任何警告或错误。哪一个是正确的,这个函数的属性的目标是什么? 如果我添加以下函数
MyVariadicPrintfT
并调用它(专用于char
),我将收到建议在此函数上使用“格式”属性的警告。我认为这是不可能的,因为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找到。
警告选项在第 3.8 节中(查找“-Wmissing-format-attribute”)。
函数属性在第 6.30 节中(查找“格式(原型,字符串索引,首先检查)”)。
谢谢。