GCC __attribute__特性的妙用

本文介绍了GCC编译器的一个强大特性__attribute__,特别是如何利用__attribute__((format(printf,m,n)))来确保printf-like函数调用的正确性。通过具体示例展示了如何在编译阶段检查函数调用的格式字符串及其参数,从而帮助开发者早期发现并修正错误。

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

<!-- lang: cpp -->

然后用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

转载于:https://my.oschina.net/jonas1q84/blog/115688

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值