Beside the fact that this is undefined behavior we can try to consider what happen in your case. But beware, this depends also on the compiler and the underlying machine. In this answer Im using VC++ 2010 on an x86 machine.
Take a look at the code
#include "stdafx.h"
int main(int argc, _TCHAR* argv[])
{
unsigned int a = 1;
printf("%d",a<<-1);
a = 1;
printf("%d",a<<31);
}
Both shifts give the same answer. To see what happen we need to take a look to the disassembly in this case.
010E1A4E mov dword ptr [a],1
010E1A55 mov eax,dword ptr [a]
010E1A58 shl eax,0FFh
...
010E1A73 mov dword ptr [a],1
010E1A7A mov eax,dword ptr [a]
010E1A7D shl eax,1Fh
...
The negativ shift is compiled to shl eax, 0ffh
. For the x86 the displacement of the shift instruction can only be 8bit thats the reason why the compiler here using (-1 & 0xff) = 0xff
. But the instruction itself will mask this constant by 0x1f
. Therefore both shifts have the same result.
After execution of the shift the result will be 0x80000000
which is as integer (please note you use %d
in printf
) the same as -2147483648.