5

If you have some variable (on the stack) and you left or right bit shift beyond its end what happens?

i.e.

byte x = 1;
x >> N;

What if x is a pointer to memory cast to a byte and you do the same thing?

byte* x = obtain pointer from somewhere;
*x = 1;
*x >> N;
nmichaels
  • 49,466
  • 12
  • 107
  • 135
Percy Flarge
  • 427
  • 1
  • 5
  • 6
  • Counterquestion: If you expect the bits from that memory location to be shifted in the next one, what would happen next? Would that mean that the bits from the next memory location will be shifter further? With this logic all the memory will became shifted. Don't you think that it have to stop somewhere instead? – ruslik Dec 02 '10 at 00:09
  • the real question then is, what would happen at the very first and last bits at the edge of the memory space. ;) – jalf Dec 02 '10 at 05:10
  • @jalf: It's not a problem if there are at least two parallel universes. – ruslik Dec 02 '10 at 10:27

3 Answers3

9

It does not (necessarily) become zero. The behavior is undefined (C99 §6.5.7, "Bitwise shift operators"):

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.

(C++0x §5.8, "Shift operators"):

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

The storage of the value being shifted has no effect on any of this.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 4
    Uh... neither "the right operand is negative" nor "the right operand is greater than or equal to the width of the promoted left operand" is necessarily the case here. The OP hasn't specified the value of N. I read the question as "I figure the value doesn't matter here, since `x` is 1". – Karl Knechtel Dec 02 '10 at 00:00
  • important note: *width* in this case means `CHAR_BIT * sizeof(var)`, and not `log2(var)`! – ruslik Dec 02 '10 at 00:00
  • And over the years I have seen exactly two behaviors for N greater than or equal to the word size. Behavior 1, by far the most common, is that all the bits "shift out" and the result is zero. The other behavior is that N is silently reduced modulo the wordsize. As an example, x >> 32 on this architecture was simply a no-op for 32-bit type x. – President James K. Polk Dec 02 '10 at 00:20
  • @GregS: Other behaviors are possible (and do occur in the real world). For example, with most compilers on ARM, a variable shift amount is reduced modulo 256 then saturated to the range 0-32 (this is what the hardware does; a few compilers emit extra instructions to get different behavior, but most do not). I've seen several other behaviors as well. – Stephen Canon Dec 02 '10 at 01:48
6

I think you're confused about what bitshifts do. They are arithmetic operators equivalent to multiplication or division by a power of 2 (modulo some weirdness about how C treats negative numbers). They do not move any bits in memory. The only way the contents of any variable/memory get changed are if you assign the result of the expression back somewhere.

As for what happens when the righthand operand of a bitshift operator is greater than or equal to the width of the type of the lefthand expression, the behavior is undefined.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
3

I think you're confused. x >> y does not actually change x in the first place. It calculates a new value.

As Stephen noted, y must not be negative, and it must be less than "the width of the promoted left operand" (read up on type promotion). But otherwise, bits that shift "off the end" are simply discarded. 1 >> 2 (notice that 2 is not negative, and it is less than the number of bits used to represent 1, which is probably 32 but certainly at least 16) evaluates to 0.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153