当我执行左移十六进制时,我输出-1作为输出,使用以下代码:
unsigned int i,j=0;
i= (0xffffffff << (32-j));
printf("%d",i);
同样,当我将shift值更改为32时,输出为0,但我从编译器收到警告(left shift count >= width of type)
unsigned int i,j=32;
i= (0xffffffff << (32));
printf("%d",i);
我在两种情况下都期望得到相同的结果(即0),但是为什么在#1情况下显示错误的输出而感到困惑,在#2的情况下,结果是正确的但是编译器发出警告!
32位和64位x86计算机的结果相同。
有人可以解释上面的结果吗?
答案 0 :(得分:2)
对于32位整数,左对齐32
或更高版本是未定义的行为。这就是错误所在。
C11 6.5.7按位移位运算符
对每个操作数执行整数提升。结果的类型是 升级的左操作数。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
答案 1 :(得分:2)
将32位变量移位32会产生未定义的行为。
这是由VS-2013编译器生成的程序集:
int n = 0;
mov dword ptr [n],0
int a = 0xFFFFFFFF << 32;
mov dword ptr [a],0
int b = 0xFFFFFFFF << (32-n);
mov ecx,20h
sub ecx,dword ptr [n]
or eax,0FFFFFFFFh
shl eax,cl
mov dword ptr [b],eax
如您所见,事实上发生的事情是:
32-n
和n==0
)进行切换时,编译器会使用shl
shl
的实际结果取决于底层架构中此操作的实现。在你的处理器上,它可能需要第二个操作数模32,因此第一个操作数被移位0。
同样,上面的描述不是由标准规定的,所以它实际上取决于使用的编译器。