位移位右手操作数类型

bit-shift right-hand operand type

我想知道 C/C++ 位移运算符的正确右手操作数是什么。

在撰写本文时,内置算术类型都小于 256 位,因此一个字节就足够了。此外,x86 移位指令使用 imm8。这表明右侧操作数应该是一个 unsigned char 并且在这里使用不同的类型将需要类型转换。

这里有“最正确”的类型吗?我知道该标准对位移位的其他方面出奇地宽松,所以也许这是另一种情况?

任何整数类型都可以用作移位的右操作数,只要该值至少为 0 且小于左操作数的位长度即可。

这在 C standard 的第 6.5.7 节 p2 和 p3 中关于位移运算符的部分有详细说明:

2 Each of the operands shall have integer type

3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

因此,虽然 unsigned char 的范围应该足以容纳任何有效值,但无论如何,正确的操作数将被提升为 int

C 倾向于希望做任何事情至少为 int,所以如果 <<>> 的 RHS 被指定为 [=14,那将是非常令人惊讶的=] 或 unsigned char.

很难想象为什么程序员会在那里使用 long(或者,上帝帮助我们,long long),但我只是尝试了这段代码:

int main()
{
    int x = 16;
    long int y = 2;
    int z1 = x << y;
    int z2 = x >> y;
    printf("%d %d\n", z1, z2);

    long long int y2 = 2;
    z1 = x << y2;
    z2 = x >> y2;
    printf("%d %d\n", z1, z2);
}

我在两个编译器下编译,都没有给出任何警告,两个程序都打印了64 4。 (不是决定性的测试,但具有启发性。)