我有以下代码
char x ='s', y='e';
if((x+(y<<16)) == ('a'+('b'<<16)))
//do something
switch (x+(y<<16)) {
case 'a'+('b'<<16):
//do something
break;
if
和switch
中的比较是否存在任何投射问题?
答案 0 :(得分:2)
你打算将第二个值按16位进行位移,*然后再添加第一个值?如果是这样,那么您将遇到问题,因为+
的优先级高于<<
以下两个表达式证明了这一点:
'a' + 'c' << 16
'b' + 'b' << 16
评估给了我们:
printf("%X : %X\n", 'a' + 'c' << 16, 'b' + 'b' << 16);
结果是:
C40000 : C40000
这是因为'a'
和'c'
都被提升为int
,添加完成,然后左移16位。与'b'
和'b'
相同。自('a' + 'c') == ('b' + 'b')
起,结果相同。
如果您打算(或假设)这样做:
'a' + ('c' << 16)
'b' + ('b' << 16)
printf("%X : %X\n", 'a' + ('c'<<16), 'b' + ('b'<<16));
结果是:
630061 : 620062
我怀疑你正试图去做什么。如果没有,并且你依赖于当前的评估优先级,那么你可能对你拥有的东西很好。
编辑更新了问题内容的更改:
每次都不应该有铸造问题。所有值都编译器升级为int
,以便进行当前编写的评估。如果您计划将结果分配给小于int
的内容,那么您将遇到问题。即使是16位的short
也不够宽,因为这是你的移位深度。你需要至少24位的空间来进行适当的评估,你的实现int
可能会授予它,除非你在一些半生不熟的嵌入式系统上(我看到过更奇怪的东西)。
答案 1 :(得分:1)
最好放一些括号以避免操作员优先级问题:
#define MYMACRO(X,Y) ((X)+(Y)<<16)
或者可能发生意外情况:
switch(MYMACRO(a+1,b+1)) // expands into switch(a+1+b+1<<16)
答案 2 :(得分:0)
看看像这样展开会发生什么
MYMACRO(1<<2, 2<<3)+1
所以
define MYMACRO(X,Y) X+Y<<16
应该是
define MYMACRO(X,Y) ((X)+(Y)<<16)
答案 3 :(得分:0)
没有铸造问题。
编译器会将x + y提升为int并将其向左移16,然后进行整数比较。
为了便于阅读,假设您需要无符号的int比较,可以按如下方式编写代码。
`if(( (unsigned)(x+y)<<16u) == ( (unsigned)('a'+'b')<<16u)) `