这里是一个小的一段代码:如何使用GCC属性'格式'?
#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行(CA从011到MyPrintf
),这表明MyVariadicPrintf
可以使用“格式”属性。
所以我添加的属性这样(很肯定这是对这段时间):
void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2)));
现在我得到的第22行预期的警告(来电MyVariadicPrintf
):
太少格式参数
- 我这样做是正确的吗?
- 我注意到,在
MyPrintf
声明中,如果我删除属性部分,我仍然会在第22行得到想要的警告。我还注意到,在该属性部分中,将索引从1更改为2将不会给出警告或错误。哪一个是正确的,这个函数的属性的目标是什么? 如果我添加以下函数
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”)。
函数属性在section 6.30(查找“格式(原型,字符串索引,首先检查)”)。
谢谢。
在MyVariadicPrintf中,我明白编译器会检查从位置2开始的参数的数量和类型,而不是位置1处的字符串。但是在MyPrintf的情况下,编译器检查了什么? – Guillaume 2009-06-16 15:10:54