5.8/2 says that it interprets it as a bit-pattern, which is only implementation dependent if for some reason your implementation doesn't use 2's complement, or if your compiler second-guesses you (they don't). C++11 is more explicit, but says the same thing.
Signed integers use what's known as 2's complement. Basically if you bit-shift a signed integer by 1, if it's positive and below 2^(bits - 2) it will work as if it were unsigned. If it is above that but positive, you will create a strange negative number that bears no relation to the original. If it is negative to begin with, you'll get possibly a negative, possibly a positive number.
For instance, if we have an 8-bit signed integer representing -1:
11111111 // -1
If we left-shift that we end up with
11111110 // -2
However, let's say we have -120
10001000 // -120
We shall end up with
00010000 // 16
Obviously that is not correct!
Continuing, using number 65:
01000001 // 65
Shifted left, this will become:
10000001 // -127
Which equates to -127.
However, the number 16:
00010000 // 16
Shifted left is
00100000 // 32
As you can see, it "sometimes works, sometimes doesn't" but usually works if your number is below 2^(bits-2) and sometimes but not usually if it is above -(2^(bits-2)). That is, to shift left by 1. To shift left by 2, take another bit off. Etc.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…