GCC有一個很好的特性__attribute__,能夠告知編譯器某個聲明的屬性,從而在編譯階段檢查引用該符號的地方調用方式是否符合其屬性,從而產生警告信息,讓錯誤儘早發現。html
attribute format 在printf-like或者scanf-like的函數聲明處加入__attribute__((format(printf,m,n)))或者__attribute__((format(scanf,m,n)));表示在編譯時對該函數調用位置進行檢查。數字m表明format string的是第幾個參數,n表明變長參數位於第幾個參數。舉個直觀的例子。shell
<!-- lang: cpp --> // gccattr.c extern void myprintf(const int level, const char *format, ...) __attribute__((format(printf, 2, 3))); // format位於第2個參數,變長參數...位於第3個參數開始 void func() { myprintf(1, "s=%s\n", 5); myprintf(2, "n=%d,%d,%d\n", 1, 2); }
<!-- lang: cpp -->函數
而後用gcc編譯這個文件,注意要打開編譯告警-Wallcode
<!-- lang: shell --> $ gcc -Wall -c gccattr.c -o gccattr.o gccattr.c: In function ‘func’: gccattr.c:5: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘int’ gccattr.c:7: warning: too few arguments for format
能夠看到,編譯器根據attribute檢查了myprintf函數的參數,因爲變長參數類型不正確而出現了告警。這個檢查能夠避免誤用參數致使程序崩潰,例如 myprintf(1, "s=%s\n", 5) 會形成訪問無效地址段錯誤。orm
__attribute__還有其餘的聲明特性,可用在變量或者類型檢查上,更多特性可參考gnu的手冊: http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.htmlhtm
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.htmlget