一个关于数据类型转换的C语言陷阱,大家注意一下

2019-12-09 19:20发布

平时写法不规范的时候,编译器都有提醒,今天不知道咋的没有提醒,就进到陷阱了,在此记录一下,也起提醒作用。
下面是抽象出来的代码,按照以下写法,会运行到Failed里面,aa-bb的值打印出来为4,比较纳闷,4>-3怎么还是进到下面的分支了。
如果使用前进行一下类型转换,改成 aa - (int32_t )bb,就会进行到正常分支,之前以为编译器会自动转换。使用minGW和VS运行结果相同
  1.     int32_t aa = 5;
  2.     uint32_t bb = 1;
  3.     if ((aa - bb) > -3)
  4.     {
  5.         sprintf ("Passed aa-bb=%d", aa - bb);
  6.     } ///if (aa-bb>-3)
  7.     else
  8.     {
  9.          sprintf ("Failed aa-bb=%d", aa - bb);
  10.     }///if (aa-bb>-3)
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
21条回答
1a2b3c
1楼-- · 2019-12-10 19:43
前几天不是还有人说keil的bug嘛,和这个完全一样的。 倒是还真没有去想到怎么会拿一个有符号数去和无符号数值比较呢,我自己从来不去这样做,因为自己认为这个是不可能的事情,不等价,因为从来没有专门学过编程语言,就自己折腾一下,可能反而胆子小不敢这样直接去整:)
wudicgi
2楼-- · 2019-12-11 01:12
1a2b3c 发表于 2019-9-16 23:27
前几天不是还有人说keil的bug嘛,和这个完全一样的。 倒是还真没有去想到怎么会拿一个有符号数去和无符号数 ...

有符号和无符号数比较还是经常能碰到的,一般都是在假定两个数都是非负数的情况下
比如 sizeof() 和 strlen() 等的值是 size_t 类型的,而实际上有时会用 int 类型存储长度 (比如有时想用负数代表其他含义),这样一比较就是有符号数和无符号数比较了
当然这样写风险肯定是有的
wzbwzb
3楼-- · 2019-12-11 01:55
这个有风险
cht-rtos
4楼-- · 2019-12-11 02:05
 精彩回答 2  元偷偷看……
takashiki
5楼-- · 2019-12-11 07:44
1a2b3c 发表于 2019-9-16 23:27
前几天不是还有人说keil的bug嘛,和这个完全一样的。 倒是还真没有去想到怎么会拿一个有符号数去和无符号数 ...


不一样。Keil的那个是Keil的BUG,而这个是程序员的锅。
为什么呢?
因为C语言规定了整型提升的条件。Keil中,unsigned char和signed char都是可以自动提升到int的,因此可以直接比较,只是产生的代码会变多,Keil为了降低资源占用它自己搞得不标准了。符合标准的编译器下(unsigned char) 12 > -1是必须成立的,无论是8位、16位、32位、64位的编译器。
prince2010
6楼-- · 2019-12-11 11:32
我之前也注意过这个问题,发过一个帖子——

https://www.amobbs.com/thread-5655050-1-1.html

一周热门 更多>