To be pedantic, the only compliant C is the one in Ian's answer.
The reason can be found in the standard (from C99 draft,
6.5.7, Bitwise shift operators, emphasis mine):
4
The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1×2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1×2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
What this means in layman terms is that if your shift affects the sign bit in a signed number, the result is not defined (actually, worse: undefined behavior).
Will it work? Yes, often, but it's not guaranteed to and it can change from compiler to compiler and even with revisions of the same compiler on the same architecture.
In general, shift operators are more safely used with unsigned integers.
Ian's answer is only relying on the internal representation of integers to be 2's complement, that is an implementation defined aspect (not undefined: the compiler vendor must provide this information) and, nowadays, an almost safe assumption. It's also definitely cleaner and shorter.