如何让GCC检查类printf函数的参数
2014-01-15 19:17
176 查看
来篇又短又水的。
大家都知道在c语言中有一类可变参数(variable-argument)的函数,像printf、scanf,这类函数的一大优势是输入参数的数量和类型都可以自由控制,但是问题也很明显,如果可变参数输入的个数或者类型不对,正常情况下编译器检查不出这样的错误,而实际运行却可能破坏堆栈,导致一些古怪的运行结果,很难定位到问题。
gcc中使用__attribute__format 可以解决这个问题。该__attribute__属性可以给被声明的函数加上类似printf或者scanf的特征,从而使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。
format的语法格式为:
format (archetype, string-index, first-to-check)
format属性告诉编译器,按照printf, scanf,
strftime或strfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
具体使用格式如下:
__attribute__((format(printf,m,n)))
__attribute__((format(scanf,m,n)))
其中参数m与n的含义为:
m:第几个参数为格式化字符串(format string);
n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,如果是在类成员函数中使用,还要考虑到隐藏的this指针。
举个例子:
1:
2:extern void myprint(const char *format,…)
__attribute__((format(printf,1,2)));
3:
4:void test()
5:{
6: myprint(“i=%d\n”,6);
7: myprint(“i=%s\n”,6);
8: myprint(“i=%s\n”,”abc”);
9: myprint(“%s,%d,%d\n”,1,2);
10:}
运行$gcc –Wall –c attribute.c attribute后,输出结果为:
attribute.c: In function `test’:
attribute.c:7: warning: format argument is not a pointer (arg 2)
attribute.c:9: warning: format argument is not a pointer (arg 2)
attribute.c:9: warning: too few arguments for format
如果不加__attribute__则不会有后面的warning。__attribute__还有许多其它的属性,具体看以参看百度文库
原文见:http://blog.huanghao.me/?p=90
大家都知道在c语言中有一类可变参数(variable-argument)的函数,像printf、scanf,这类函数的一大优势是输入参数的数量和类型都可以自由控制,但是问题也很明显,如果可变参数输入的个数或者类型不对,正常情况下编译器检查不出这样的错误,而实际运行却可能破坏堆栈,导致一些古怪的运行结果,很难定位到问题。
gcc中使用__attribute__format 可以解决这个问题。该__attribute__属性可以给被声明的函数加上类似printf或者scanf的特征,从而使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。
format的语法格式为:
format (archetype, string-index, first-to-check)
format属性告诉编译器,按照printf, scanf,
strftime或strfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
具体使用格式如下:
__attribute__((format(printf,m,n)))
__attribute__((format(scanf,m,n)))
其中参数m与n的含义为:
m:第几个参数为格式化字符串(format string);
n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,如果是在类成员函数中使用,还要考虑到隐藏的this指针。
举个例子:
1:
2:extern void myprint(const char *format,…)
__attribute__((format(printf,1,2)));
3:
4:void test()
5:{
6: myprint(“i=%d\n”,6);
7: myprint(“i=%s\n”,6);
8: myprint(“i=%s\n”,”abc”);
9: myprint(“%s,%d,%d\n”,1,2);
10:}
运行$gcc –Wall –c attribute.c attribute后,输出结果为:
attribute.c: In function `test’:
attribute.c:7: warning: format argument is not a pointer (arg 2)
attribute.c:9: warning: format argument is not a pointer (arg 2)
attribute.c:9: warning: too few arguments for format
如果不加__attribute__则不会有后面的warning。__attribute__还有许多其它的属性,具体看以参看百度文库
原文见:http://blog.huanghao.me/?p=90
相关文章推荐
- Spring事务管理机制的实现原理-动态代理
- POJ 3101 Astronomy
- 01背包 决策树模型 Python
- STM8S各个模块初始化
- 黑马程序员_String对象
- bat批处理教程
- bzoj 3212 线段树
- 去除框
- 序列化和反序列化
- [算法] trie树实现
- VirtualBox为虚拟OS硬盘扩容
- 黑马程序员_多线程通信
- 常见嵌入式WEB服务器
- 宿主环境(host environment)
- HQL的多表查询 left jon 等 (需要配置一对多)
- 前台线程和后台线程的问题
- 在安装flash player 时提示不是最新的版本 && 安装失败
- Ubuntu中Git服务器搭建(做了修改)
- CodeProject上的一些摘抄
- 查看innodb表空间