编写安全代码:再论整数类型转换
浏览:2644次 出处信息
前几天看C99标准,写了两篇关于整数提升的博文,http://blog.chinaunix.net/space.php?uid=23629988&do=blog&id=2938697在这篇的评论中,pragma朋友提出了一个问题。经过了重新阅读C99,和别人讨论,外加思考,得到了答案。这再次加深了我对整数提升的理解,所以需要进一步总结一下这个问题。
先看看pragma提出的问题吧。
- #include <stdlib.h>
- #include <stdio.h>
- #define PRINT_COMPARE_RESULT(a, b) \
- if (a > b) { \
- printf( #a " > " #b "\n"); \
- } \
- else if (a < b) { \
- printf( #a " < " #b "\n"); \
- } \
- else { \
- printf( #a " = " #b "\n" ); \
- }
- int main()
- {
- signed int a = -1;
- unsigned int b = 2;
- signed short c = -1;
- unsigned short d = 2;
- PRINT_COMPARE_RESULT(a,b);
- PRINT_COMPARE_RESULT(c,d);
- return 0;
- }
输出结果为
- [root@Lnx99 test]#./a.out
- a > b
- c < d
为什么将int换为short后,结果就不一样了呢?
在C99标准中算数运算中有两种conversion,一个是integer promotion,另外一个是usual arithmetic conversions。在前面的博文中,我研究的是第二种,并将其理解为integer promotion,其实是不准确的。
下面是C99中关于第一种integer promotion的描述:
If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
——在C99的上下文,这个integer promotion发生在算术运算的时候。
而C99关于usual arithmetic conversions,参加我这篇博文:http://blog.chinaunix.net/space.php?uid=23629988&do=blog&id=2938697
这样的话,也就是说在算术运算中,会涉及两种integer conversion。上面的测试代码的结果,也是由此而来。
下面开始分析:
对于a和b来说,integer promotion相当于不起作用,所以只进行usual arithmetic conversion,根据规则,将a转为unsigned int,所以a>b。
对于c和d来说,首先integer promotion会起作用,c和d都会转为int型,也就是说相当于int c = -1,int d = 2;然后进行usual arithmetic conversion,因为两者此时都为int型,那么自然结果是c < d了。
现在答案已经清晰了,但是却让我感到一阵阵忐忑,因为这样的整数转换规则太容易让人犯错了。对于我们来说,虽然已经比较明晰两个规则,但是在代码中还是要尽量避免有符号数和无符号数的比较。如果无法避免,为了清楚的表明自己的目的,最好使用强制类型转换。
建议继续学习:
- STRUTS2类型转换错误导致OGNL表达式注入漏洞分析 (阅读:9163)
- PHP数据类型隐性转换的陷阱 (阅读:2975)
- javascript运算/转换技巧 (阅读:2724)
- JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] ) (阅读:2601)
- 弱类型?C语言参数提升带来的一个陷阱 (阅读:2168)
- PHP类型转换相关的一个Bug (阅读:1977)
- PHP操作MongoDB时的整数问题及对策 (阅读:1960)
- 当类型转换表达式遇上自定义转换操作 (阅读:1519)
- 大整数乘法 (阅读:1464)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:android原生浏览器不支持httponly
后一篇:编写安全代码:小心使用浮点数 >>
文章信息
- 作者:gfree.wind@gmail.com 来源: kernelchina blogs
- 标签: 整数 类型转换
- 发布时间:2012-06-20 22:50:58
建议继续学习
近3天十大热文
- [41] 界面设计速成
- [36] Oracle MTS模式下 进程地址与会话信
- [33] IOS安全–浅谈关于IOS加固的几种方法
- [33] 如何拿下简短的域名
- [32] 图书馆的世界纪录
- [32] 视觉调整-设计师 vs. 逻辑
- [32] 程序员技术练级攻略
- [31] 【社会化设计】自我(self)部分――欢迎区
- [31] android 开发入门
- [28] 读书笔记-壹百度:百度十年千倍的29条法则