我也来吐槽下海尔的编译器
下面这是个简单的程序,有两个变量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)
{
}
}这样子才可以。。。
真是够纠结的。。。。 if( a == (~b) ) sevenchrist 发表于 2013-9-8 15:29 static/image/common/back.gif
if( a == (~b) )
这个我有试过。。没有用的。。。 这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a=0xff,b=0;则a可能被提升至0x00ff,b位0x0000,这时肯定不会a==~b了,可修改为
(unsigned char)a==(unsigned char)~b zhangshixing 发表于 2013-9-8 15:53 static/image/common/back.gif
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...
这个理由我到是可以接受,比较疑惑的是我用的是8位的单片机,我定义的两个相比较的变量也是8位的,为啥要给我提升为16位的,而且这个情况在别的平台下还未遇到过 zhangshixing 发表于 2013-9-8 15:53 static/image/common/back.gif
这个不是编译器的问题啊,我也碰到过的,是你编程的问题,因为C语言的默认整数提升,导致运行不正确
例如a= ...
如果這是8位處理器,編譯器也將unsigned char變爲unsigned int,那麼就實在是反人類了。 本帖最后由 twitter 于 2013-9-8 17:13 编辑
C89、C99标准中,按位操作的操作符(包括了 ~、&、^、|、<<、>>)需要整型作为操作数,所以按这些标准,字符型将被扩展为int类型作运算。
http://www.amobbs.com/thread-795415-1-1.html
无符号的0xfe提升为0x00fe(如果int是16位的),取反的结果是0xff01,和a不等的。 asj1989 发表于 2013-9-8 15:46 static/image/common/back.gif
这个我有试过。。没有用的。。。
if( a == (unsigned char)(~b) ) C标准就是这样规定的啊,有的编译器和C标准这点兼容,有的不兼容,推荐还是写兼容的代码,现在也是用Keil习惯了,代码也是和C标准不兼容的很多,有些转到IAR就要报错 qlb1234 发表于 2013-9-8 16:39 static/image/common/back.gif
如果這是8位處理器,編譯器也將unsigned char變爲unsigned int,那麼就實在是反人類了。 ...
keil c51默认也是提升成16bit的,不过可以把它禁掉 楼上方法很好啊,学习学习啊 貌似~b 这种写法不正确吧。这种写法是按位取反,很多器件不支持。最好不要这样用。用!&|来组合获取比较好 起始还有一种写法,就是a==(b^0xff) zhangshixing 发表于 2013-9-9 16:51 static/image/common/back.gif
起始还有一种写法,就是a==(b^0xff)
需要那么麻烦吗,直接(unsigned char)(a+b) == 0不就行了加法哪个mcu都支持吧 "定义为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的好处,不是不能解决整型提升的问题吗? http://www.amobbs.com/thread-795415-1-1.html
LZ看下这个帖子,就会明白你的问题的原因了。别只怪编译器,只能怪你没有认真看C99标准 编译器还是很严谨的。没有搞清楚就不要乱下结论。 台系IC用多了,对各种BUG已经麻木了
页:
[1]