這裏是一個小的一段代碼:如何使用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