As per standard C its a implementation specific behavior but lets check how is gcc behaving from the following code and we can assume that most of the compiler will behave as it is
Sample Code
#include <stdio.h>
main()
{
int i=-16;
int j=16;
printf("Signed Left Shift %d\n", i<<1);
printf("UnSigned Left Shift %d\n", j<<1);
printf("Signed right Shift %d\n", i>>1);
printf("UnSigned right Shift %d\n", j>>1);
}
GCC output
Signed Left Shift -32
UnSigned Left Shift 32
Signed right Shift -8
UnSigned right Shift 8
Conclusion
From the above example we can conclude the following -
1. In the case of left shift sign bit is not shifted and also sign bit is not changed. If it is 32 bit number then sign bit remains as it is and shift is managed within the remaining 31 bits.
2. In the case of right shift also sign bit is not shifted and also sign bit is not changed. If it is 32 bit number then sign bit remains as it is and shift is managed within the remaining 31 bits.
Let me know if still have any doubts