No, you can't.
Shifts on unsigned types are well defined (as long as the right operand is in non-negative and less than the width of the left operand), and they always zero-fill.
Shifts (or any bitwise operations) on signed types are generally not a good idea. If the left operand is negative then <<
has undefined behavior, and >>
yields an implementation-defined result (meaning that the compiler has to document what it does, but there's no way for you to control it). For non-negative values of a signed type, the result is what you'd expect -- as long as it doesn't overflow (if it overflows, the behavior is undefined).
Here's what the C99 standard says (section 6.5.7):
The integer promotions are performed on each of the operands. The type
of the result is that of the promoted left operand. If the value of
the right operand is negative or is greater than or equal to the width
of the promoted left operand, the behavior is undefined.
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.
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has
an unsigned type or if E1 has a signed type and a nonnegative value,
the value of the result is the integral part of the quotient of E1 /
2E2. If E1 has a signed type and a negative value, the resulting
value is implementation-defined.
Coming back to this answer 11+ years later, an implementation certainly could offer an option to control the behavior of implementation-defined shifts. I don't know of any that do so.
I cited the C99 standard. I don't believe there have been any relevant changes in later editions.