在这种情况下是否存在铸造问题((x +(y <&lt; 16))==('a'+('b'&lt;&lt; 16)))

时间:2013-01-04 17:16:09

标签: c casting

我有以下代码

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;

ifswitch中的比较是否存在任何投射问题?

4 个答案:

答案 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))  `