当我们在coding的时候,使用两个变量相加的情况,或者用 +,或者用 | ,都是没有问题,比如:
0x1000 + 0x55 = 0x1055
0x1000 | 0x55 = 0x1055
介于以前这种固有的思维,因此没有把其中不同仔细考虑,直到这几天的bug,才恍然大悟,还是因为基础知识的不扎实和习惯性的思维导致这个bug,不过也给我了一个机会,彻底的搞清楚这两个运算符在变量相加的时候的区别。
因为code是这么定义的:
#define PCI_ADDR(bus,device,func,reg) (UINT64)(bus<<24 + device<<16 + func<<8 + reg ) & 0x00000000FFFFFFFF
#define DRAM_PCI PCI_ADDR(0,0,3,0)
UINT64 Addr;
假如我要访问寄存器0x55
(1) Addr = DRAM_PCI + 0x55;
(2) Addr = DRAM_PCI | 0x55;
那么请问(1)和(2)相等吗?
答案是: (1) Addr = 0;
(2) Addr = RealValue;
那么为什么在(1)中,Addr = 0呢,问题还是出在PCI_ADDR这个宏定义上:
因为宏定义最后做了一个与运算,所以在之后的运算中就需要和 + 或者 | 进行优先级的比较,由于+ 》 & 》 | ,因此当使用 | 的时候,就不会出现问题,能够和我们想要的运算一致;当使用 + 的时候,由于 + 比 & 优先级高,因此就率先计算了 0x00000000FFFFFFFF + 0x55,导致得到了新值 0x0000000100000054,然后和之前的数值进行 &, 不就得到了 0 嘛
所以得到的经验教训:
1)在复杂的定义面前不能想当然的去使用自己认为没有问题的运算符,因为检查这个问题可不是这么容易找到根源的。
2)在进行宏定义的时候最好给整个宏加上括号,那么就可以避免很多优先级的问题,因为调用这个宏的人可能多种多样。
3)尽可能的使用最简单的运算符进行coding,可以避免一些问题,当然如果反复调用的情况下,还是需要定义宏,当然定义要慎重,参考2)
4)基础很重要啊,要能快速的找到问题的根源还是需要熟悉各种运算符的优先级,这次又好好的复习了一下。
顺便附上C语言中常用运算符的优先级:
1 () [] -> . :: ! ~ ++ --
2 - (unary) * (dereference) & (address of) sizeof
3 ->* .*
4 * (multiply) / %
5 + -
6 << >>
7 < <= > >=
8 == !=
9 & (bitwise AND)
10 ^
11 |
12 &&
13 ||
14 ? :
15 = += -= etc.
16 ,
posted on 2009-05-22 13:18
yuhen 阅读(1421)
评论(4) 编辑 收藏 引用 所属分类:
技术文档