5

我有一个掩码程序(它为给定大小的下半部分创建一个全1的位掩码):

template<class T>
T bottom_half() {
    T halfway = ((sizeof(T) * 8) / 2);
    T mask = (1 << halfway) - 1;

    return mask;
}

如果我调用bottom_half<int>()or longor ,它工作正常char。但是由于某种原因,当我运行它时long longhalfway正确设置为,32但是。为什么会这样?mask0

4

3 回答 3

8

左移是移位 1,int默认情况下,在您的机器上可能是 32 位。当你 shift1<<32时,结果是未定义的,这意味着它不再是可预测的,因为它可能是任何东西。

在某些处理器上,1<<32可能会导致将位移出整数的高端并导致 0。在其他处理器上,32 移位是寄存器大小的模数,因此有效的是零移位,结果为 1。无论如何,它是未定义的。

(参见What's bad about shift a 32-bit variable 32 bits?进行讨论)。

另请注意,sizeof返回单位char或“字节”(这些在 C 中定义为sizeof(char) == 1始终相同),但 C 不保证一个字节是 8 位。有标准宏CHAR_BIT来获取char.

尝试这个

#include <limits.h>

template<class T>
T bottom_half() {
    T halfway = ((sizeof(T) * CHAR_BIT) / 2);
    T mask = ((T)1 << halfway) - 1;

    return mask;
}
于 2013-09-17T18:27:41.767 回答
3

表达式1 << x具有类型int。左移有符号类型以使值超过最大可表示值具有未定义的行为。改为使用T(1) << x

于 2013-09-17T18:31:25.127 回答
0

1您的班次操作转换为正确的类型。实际上,它是一个简单的整数,因此移位没有任何效果——您将位移到不存在。

于 2013-09-17T18:28:28.600 回答