It's very probably not attempting to shift by some large number of bits.
INT_MAX
on your system is probably 2**31-1
, or 0x7fffffff
(I'm using **
to denote exponentiation). If that's the case, then In the declaration:
int b = 0x80000000;
(which was missing a semicolon in the question; please copy-and-paste your exact code) the constant 0x80000000
is of type unsigned int
, not int
. The value is implicitly converted to int
. Since the result is outside the bounds of int
, the result is implementation-defined (or, in C99, may raise an implementation-defined signal, but I don't know of any implementation that does that).
The most common way this is done is to reinterpret the bits of the unsigned value as a 2's-complement signed value. The result in this case is -2**31
, or -2147483648
.
So the behavior isn't undefined because you're shifting by value that equals or exceeds the width of type int
, it's undefined because you're shifting by a (very large) negative value.
Not that it matters, of course; undefined is undefined.
NOTE: The above assumes that int
is 32 bits on your system. If int
is wider than 32 bits, then most of it doesn't apply (but the behavior is still undefined).
If you really wanted to attempt to shift by 0x80000000
bits, you could do it like this:
unsigned long b = 0x80000000;
unsigned long a = 1 >> b; // *still* undefined
unsigned long
is guaranteed to be big enough to hold the value 0x80000000
, so you avoid part of the problem.
Of course, the behavior of the shift is just as undefined as it was in your original code, since 0x80000000 is greater than or equal to the width of unsigned long
. (Unless your compiler has a really big unsigned long
type, but no real-world compiler does that.)
The only way to avoid undefined behavior is not to do what you're trying to do.
It's possible, but vanishingly unlikely, that your original code's behavior is not undefined. That can only happen if the implementation-defined conversion of 0x80000000
from unsigned int
to int
yields a value in the range 0 .. 31. IF int
is smaller than 32 bits, the conversion is likely to yield 0.