无符号整型能产生哪些bug?

为什么不建议使用无符号整型,无符号整型能产生哪些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 1111111011111111 11111111 11111111 11111111
把它转换成无符号数字,就是最高位不再表示符号位,全部用来表示实际大小。
借助下计算器,-1转换成无符号数就是这么大:4294967295
所以判断语句肯定不成立。
只要编译器的sizeof返回的是无符号整型,那么这个bug就一直存在。
对无符号类型的建议:  
尽量不要在你的代码中使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号数不存在负值(如年龄、国债)而用它来表示数量。
尽量使用像 int 那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如 -1 被翻译为非常大的正数)。
只有在使用位段和二进制掩码时,才可以用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或者无符号数,这样就不必由编译器来选择结果的类型。
嵌入式开发中使用无符号的场景很多,操作地址、寄存器等等,尤其是做单片机等等一些底层开发,随处可见 unsigned 字样,这也是由硬件特性决定。使用的时候多加注意,尤其是做一些基本运算的时候。


使用GDB调试Linux应用程序
5G换机潮要到了 手机产业链公司纷纷募资
中国最大MEMS企业歌尔股份,上半年营收451.73亿元
云天励飞边缘计算盒子助力道路维护工作从经验决策走向数据决策
全球及美国首张无人机配送商业化“驾照”先后落地
无符号整型能产生哪些bug?
mClinux系统特点深入分析
链享云科技的愿景将是打造出全球第一商用公链
全球LCD面板价格持续上涨
我们离不开的电源管理IC芯片基础知识科普
山东青岛联通推出新一代国产原研手术机器人——“妙手”主操作手
RADIO-ENERGIE法国雷恩编码器
屏下指纹识别应用爆发但国产手机核心技术缺乏
工业平板电脑其实就是工业控制带显示触摸一体的电脑
视频会议与视频直播,视频点播有什么区别?
人工智能助力教师建设智能化教学
μCOS-II软件定时器的分析与测试
OPPO宣布正式对外授权VOOC闪充技术 皮卡丘作为OPPO超级闪充电力大使亮相
十余家中国VR公司得到HTC Vive X资助
关于PLC学习的一些基础知识