asj1989 发表于 2013-9-8 15:02:46

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

下面这是个简单的程序,
有两个变量a和b,并且a,b的内容互补。

然后if判断ab是否互补。

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

unsigned char a;
unsigned char b;

void main()
{
    PCT4 = 0;
    PC4 = 0;
   
    a = 0x01;
    b = 0xfe;
   
    if( a == ~b )//这里判断不通过
    {
      PC4 = 1;
    }
   
    while(1)
    {
    }
}
必须这么写
再定义个变量
unsigned char c;#include "hic.h"
#include "hr7p90h.h"

unsigned char a;
unsigned char b;
unsigned char c;

void main()
{
    PCT4 = 0;
    PC4 = 0;
   
    a = 0x01;
    b = 0xfe;
   
    c = ~b;
   
    if( a == c )//这里会判断通过
    {
      PC4 = 1;
    }
   
    while(1)
    {
    }
}这样子才可以。。。

真是够纠结的。。。。

sevenchrist 发表于 2013-9-8 15:29:53

if( a == (~b) )

asj1989 发表于 2013-9-8 15:46:07

sevenchrist 发表于 2013-9-8 15:29 static/image/common/back.gif
if( a == (~b) )

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

zhangshixing 发表于 2013-9-8 15:53:30

这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a=0xff,b=0;则a可能被提升至0x00ff,b位0x0000,这时肯定不会a==~b了,可修改为
(unsigned char)a==(unsigned char)~b

asj1989 发表于 2013-9-8 16:30:47

zhangshixing 发表于 2013-9-8 15:53 static/image/common/back.gif
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...

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

qlb1234 发表于 2013-9-8 16:39:27

zhangshixing 发表于 2013-9-8 15:53 static/image/common/back.gif
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...

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

twitter 发表于 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不等的。

sevenchrist 发表于 2013-9-8 17:22:12

asj1989 发表于 2013-9-8 15:46 static/image/common/back.gif
这个我有试过。。没有用的。。。


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

zhangshixing 发表于 2013-9-9 08:00:39

C标准就是这样规定的啊,有的编译器和C标准这点兼容,有的不兼容,推荐还是写兼容的代码,现在也是用Keil习惯了,代码也是和C标准不兼容的很多,有些转到IAR就要报错

zhugean 发表于 2013-9-9 08:50:30

qlb1234 发表于 2013-9-8 16:39 static/image/common/back.gif
如果這是8位處理器,編譯器也將unsigned char變爲unsigned int,那麼就實在是反人類了。 ...

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

zhangshixing 发表于 2013-9-9 16:08:12

楼上方法很好啊,学习学习啊

zf12862177 发表于 2013-9-9 16:44:52

貌似~b 这种写法不正确吧。这种写法是按位取反,很多器件不支持。最好不要这样用。用!&|来组合获取比较好

zhangshixing 发表于 2013-9-9 16:51:20

起始还有一种写法,就是a==(b^0xff)

myxiaonia 发表于 2013-9-16 12:05:16

zhangshixing 发表于 2013-9-9 16:51 static/image/common/back.gif
起始还有一种写法,就是a==(b^0xff)

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

wxty 发表于 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的好处,不是不能解决整型提升的问题吗?

laujc 发表于 2013-9-16 14:55:27

http://www.amobbs.com/thread-795415-1-1.html
LZ看下这个帖子,就会明白你的问题的原因了。别只怪编译器,只能怪你没有认真看C99标准

kebaojun305 发表于 2013-9-16 15:24:29

编译器还是很严谨的。没有搞清楚就不要乱下结论。

ijlc1314 发表于 2013-9-16 16:14:56

台系IC用多了,对各种BUG已经麻木了
页: [1]
查看完整版本: 我也来吐槽下海尔的编译器