1

我有以下代码

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

4

4 回答 4

2

您是否打算将第二个值移位 16 位 *then,然后添加第一个?如果是这样,那么您将遇到问题,因为+优先级高于<<

以下两个表达式证明了这一点:

'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您将遇到问题的东西。即使是short16 位的 a 也不够宽,因为那是您的移位深度。您需要至少 24 位的空间来进行正确的评估,并且您的实现int可能会同意这一点,除非您在一些半生不熟的嵌入式系统上(我见过奇怪的事情)。

于 2013-01-04T18:00:09.327 回答
1

最好加上一些括号以避免运算符优先级问题:

#define MYMACRO(X,Y) ((X)+(Y)<<16)

否则可能会发生意想不到的事情:

switch(MYMACRO(a+1,b+1)) // expands into switch(a+1+b+1<<16)
于 2013-01-04T17:22:20.230 回答
0

没有铸造问题。

编译器会将 x + y 提升为 int 并将其左移 16,然后进行整数比较。

为了便于阅读,假设您需要 unsigned int 比较,您可以将其编码如下。

`if((  (unsigned)(x+y)<<16u) == ( (unsigned)('a'+'b')<<16u))  `
于 2013-01-04T18:05:31.240 回答
0

看看像这样展开时会发生什么

MYMACRO(1<<2, 2<<3)+1

所以

define MYMACRO(X,Y) X+Y<<16

应该

define MYMACRO(X,Y) ((X)+(Y)<<16)
于 2013-01-04T17:25:18.383 回答