如果我使用3 << 32
,则会得到正确的结果。
如果我使用sizeof(int)
找到大小,然后乘以8,将结果存储在变量中,然后使用3 << variable
,则会得到不同的结果。我在这里想念什么?
void func()
{
unsigned int sz = sizeof(number) * 8;
unsigned int k = 0;
printf("Value of sz is %u \r\n",sz);
k = (k | (0x3) << sz);
printf("Value of 2_1_MSB is %d \r\n",(3 << 32));
printf("Value of k is %u \r\n",k);
}
答案 0 :(得分:5)
C标准仅针对仅小于要转换类型的宽度的转换定义转换行为(C 2018 6.5.7 3)。标准未定义将32位int
移32位。
3 << 32
和(0x3) << sz
之间可能存在差异,这是由于编译器在编译时评估前者(也许使用了将所有位移出,导致为零的操作)而后者在执行时评估的原因(也许使用一条仅使用移位量的低五位的指令,而不会产生移位)。可能不依赖此类行为;它们可能会随着优化,目标或其他编译器配置的更改,编译器版本的更改等而改变。
答案 1 :(得分:5)
在所有现代PC型平台上,int
只有32位。移位超过未定义。并且请记住,用于移位的位数是从零开始的,因此对于32位类型(如int
),有效位数范围是0
至31
(包括两端)。>
现在了解3 << 32
和3 << sz
之间的区别:在第一种情况下,编译器可以知道它要移位32位以上,因此可以推断出它将是64位操作(使用long long
)。在第二种情况下,编译器不知道sz
的值,因为它是一个普通变量,而不是编译时常量。因此,必须假定这是一个简单的int
移位,并且sz
的值在范围内。