搜索
bottom↓
回复: 18

我也来吐槽下海尔的编译器

[复制链接]

出0入131汤圆

发表于 2013-9-8 15:02:46 | 显示全部楼层 |阅读模式
下面这是个简单的程序,
有两个变量a和b,并且a,b的内容互补。

然后if判断ab是否互补。

纠结的是 if( a == ~b )这样子压根就不通过。。。
  1. #include "hic.h"
  2. #include "hr7p90h.h"

  3. unsigned char a;
  4. unsigned char b;

  5. void main()
  6. {
  7.     PCT4 = 0;
  8.     PC4 = 0;
  9.    
  10.     a = 0x01;
  11.     b = 0xfe;
  12.    
  13.     if( a == ~b )//这里判断不通过
  14.     {
  15.         PC4 = 1;
  16.     }
  17.    
  18.     while(1)
  19.     {
  20.     }
  21. }
复制代码
必须这么写
再定义个变量
unsigned char c;
  1. #include "hic.h"
  2. #include "hr7p90h.h"

  3. unsigned char a;
  4. unsigned char b;
  5. unsigned char c;

  6. void main()
  7. {
  8.     PCT4 = 0;
  9.     PC4 = 0;
  10.    
  11.     a = 0x01;
  12.     b = 0xfe;
  13.    
  14.     c = ~b;
  15.    
  16.     if( a == c )//这里会判断通过
  17.     {
  18.         PC4 = 1;
  19.     }
  20.    
  21.     while(1)
  22.     {
  23.     }
  24. }
复制代码
这样子才可以。。。

真是够纠结的。。。。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2013-9-8 15:29:53 | 显示全部楼层
if( a == (~b) )

出0入131汤圆

 楼主| 发表于 2013-9-8 15:46:07 | 显示全部楼层
sevenchrist 发表于 2013-9-8 15:29
if( a == (~b) )

这个我有试过。。没有用的。。。

出0入0汤圆

发表于 2013-9-8 15:53:30 | 显示全部楼层
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a=0xff,b=0;则a可能被提升至0x00ff,b位0x0000,这时肯定不会a==~b了,可修改为
(unsigned char)a==(unsigned char)~b

出0入131汤圆

 楼主| 发表于 2013-9-8 16:30:47 | 显示全部楼层
zhangshixing 发表于 2013-9-8 15:53
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...

这个理由我到是可以接受,比较疑惑的是我用的是8位的单片机,我定义的两个相比较的变量也是8位的,为啥要给我提升为16位的,而且这个情况在别的平台下还未遇到过

出0入0汤圆

发表于 2013-9-8 16:39:27 | 显示全部楼层
zhangshixing 发表于 2013-9-8 15:53
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...

如果這是8位處理器,編譯器也將unsigned char變爲unsigned int,那麼就實在是反人類了。

出0入0汤圆

发表于 2013-9-8 17:02:30 | 显示全部楼层
本帖最后由 twitter 于 2013-9-8 17:13 编辑

C89、C99标准中,按位操作的操作符(包括了 ~、&、^、|、<<、>>)需要整型作为操作数,所以按这些标准,字符型将被扩展为int类型作运算。
http://www.amobbs.com/thread-795415-1-1.html

无符号的0xfe提升为0x00fe(如果int是16位的),取反的结果是0xff01,和a不等的。

出0入0汤圆

发表于 2013-9-8 17:22:12 | 显示全部楼层
asj1989 发表于 2013-9-8 15:46
这个我有试过。。没有用的。。。


if( a == (unsigned char)(~b) )

出0入0汤圆

发表于 2013-9-9 08:00:39 | 显示全部楼层
C标准就是这样规定的啊,有的编译器和C标准这点兼容,有的不兼容,推荐还是写兼容的代码,现在也是用Keil习惯了,代码也是和C标准不兼容的很多,有些转到IAR就要报错

出0入0汤圆

发表于 2013-9-9 08:50:30 | 显示全部楼层
qlb1234 发表于 2013-9-8 16:39
如果這是8位處理器,編譯器也將unsigned char變爲unsigned int,那麼就實在是反人類了。 ...

keil c51默认也是提升成16bit的,不过可以把它禁掉

出0入0汤圆

发表于 2013-9-9 16:08:12 | 显示全部楼层
楼上方法很好啊,学习学习啊

出0入0汤圆

发表于 2013-9-9 16:44:52 | 显示全部楼层
貌似~b 这种写法不正确吧。这种写法是按位取反,很多器件不支持。最好不要这样用。用!&|来组合获取比较好

出0入0汤圆

发表于 2013-9-9 16:51:20 | 显示全部楼层
起始还有一种写法,就是a==(b^0xff)

出0入0汤圆

发表于 2013-9-16 12:05:16 | 显示全部楼层
zhangshixing 发表于 2013-9-9 16:51
起始还有一种写法,就是a==(b^0xff)

需要那么麻烦吗,直接(unsigned char)(a+b) == 0不就行了  加法哪个mcu都支持吧

出0入0汤圆

发表于 2013-9-16 14:41:59 | 显示全部楼层
"定义为uint8_t并不会改变这个结果。因为avr-gcc默认的整型是16位的,那么按c标准,这些运算总是会把8位扩展为编译器设置的整型大小(即16位)。
另外,虽然avr-libc手册上说uint8_t是定义成:
typedef unsigned char uint8_t;
但实际上不是这样的,手册是Doxygen生成的,stdint.h里这些整型定义于:
#if defined(__DOXYGEN__)
...(这里是手册里看到的定义)
#else
...(这里是实际定义)
#endif
默认情况下,这两处定义是等价的。但是如果更改编译参数的话,就不同了(也涉及到代码优化的一个方法)。
实际定义拥有更好的移植性和优化性。
建议用avr-gcc的话,不要像我在一楼里那样定义变量,而是用uint8_t之类(我现在移植过来的代码已经全改成此类定义了)。"

可能我还是没有看懂用uint8的好处,不是不能解决整型提升的问题吗?

出0入4汤圆

发表于 2013-9-16 14:55:27 | 显示全部楼层
http://www.amobbs.com/thread-795415-1-1.html
LZ看下这个帖子,就会明白你的问题的原因了。别只怪编译器,只能怪你没有认真看C99标准

出0入8汤圆

发表于 2013-9-16 15:24:29 | 显示全部楼层
编译器还是很严谨的。没有搞清楚就不要乱下结论。

出0入0汤圆

发表于 2013-9-16 16:14:56 | 显示全部楼层
台系IC用多了,对各种BUG已经麻木了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 09:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表