如果我使用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);
}
在所有现代PC类平台,int
只有32位。超过该转移是不确定的。并记住,比特数为是基于零的,因此对于一个32位的类型(如int
),那么有效位的范围是0
到31
(含)移位。
现在对于3 << 32
和3 << sz
之间的差:在第一情况下,编译器可以知道它移超过32位,因此它可以推断出,这将是一个64位操作(使用long long
)。在第二种情况下,编译器不知道sz
的价值,因为它是一个简单的变量,而不是一个编译时间常数。因此,它必须假定,这是一个简单的移位int
和sz
的值的范围。
C标准仅定义为偏移小于类型的宽度被移位(C 2018 6.5.7 3)移行为。由32位移位32位int
不是由标准限定。
由于编译器评价在编译时前者3 << 32
和(0x3) << sz
可能出现之间的差异(可能使用了这一点改变所有的位,导致零的操作)和在执行时后者(可能使用仅使用低5位的指令的移位量的,导致没有偏移)。这种行为可能不能依靠;他们可能与优化,目标或其他编译器配置的变化,编译器版本的变化而变化,等等。