GCC __attribute__特性的妙用

GCC有一个很好的特性attribute,可以告知编译器某个声明的属性,从而在编译阶段检查引用该符号的地方调用方式是否符合其属性,从而产生警告信息,让错误尽早发现。

attribute format
在printf-like或者scanf-like的函数声明处加入attribute((format(printf,m,n)))或者attribute((format(scanf,m,n)));表示在编译时对该函数调用位置进行检查。数字m代表format string的是第几个参数,n代表变长参数位于第几个参数。举个直观的例子。

<!-- 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);    
}

然后用gcc编译这个文件,注意要打开编译告警-Wall

<!-- 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) 会造成访问无效地址段错误。

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.html

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.html

你可能感兴趣的:(gcc,format,__attribute__)