为什么不建议使用无符号整型,无符号整型能产生哪些bug?
《C专家编程》有这么几行代码。
#include一个数组,一个宏定义,宏的作用就是计算数组的元素个数。int array[] = {23, 34, 12, 17, 204, 99, 16}; #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int main() { int d = -1, x; /* ... */ if (d <= TOTAL_ELEMENTS - 2) x = array[d + 1]; /* ... */ return 0; }
主函数里面d初始化成-1,判断语句中用 d 跟 TOTAL_ELEMENTS - 2做比较,如果成立,则给 x 赋值。
代码很简单,乍一看,-1 确实小于 5,于是判断语句肯定成立。
问题就出在了这边。
d属于有符号整型,TOTAL_ELEMENTS因为是sizeof的求值结果,所以它属于无符号整型,把这两个放在一起运算,很显然属于混合运算。
一个是有符号一个是无符号,编译器默认把有符号数转换成无符号数,接下来我们可以算一下。
-1的二进制是这样的:
10000000 00000000 00000000 00000001
因为负数在内存中是以补码的形式存放,所以先转换成反码,再转换成补码。
11111111 11111111 11111111 11111110 11111111 11111111 11111111 11111111
把它转换成无符号数字,就是最高位不再表示符号位,全部用来表示实际大小。
借助下计算器,-1转换成无符号数就是这么大:
4294967295
所以判断语句肯定不成立。
只要编译器的sizeof返回的是无符号整型,那么这个bug就一直存在。
对无符号类型的建议:
尽量不要在你的代码中使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号数不存在负值(如年龄、国债)而用它来表示数量。
尽量使用像 int 那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如 -1 被翻译为非常大的正数)。
只有在使用位段和二进制掩码时,才可以用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或者无符号数,这样就不必由编译器来选择结果的类型。
嵌入式开发中使用无符号的场景很多,操作地址、寄存器等等,尤其是做单片机等等一些底层开发,随处可见 unsigned 字样,这也是由硬件特性决定。使用的时候多加注意,尤其是做一些基本运算的时候。
审核编辑:汤梓红
-
嵌入式
+关注
关注
5082文章
19117浏览量
304963 -
寄存器
+关注
关注
31文章
5342浏览量
120297 -
编程
+关注
关注
88文章
3615浏览量
93710 -
代码
+关注
关注
30文章
4786浏览量
68556
原文标题:为什么不建议使用无符号整型
文章出处:【微信号:学益得智能硬件,微信公众号:学益得智能硬件】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论