Weird bit-shift behavior on void*.

C. Dunn cdunn2001 at gmail.com
Fri Aug 10 13:03:19 PDT 2007


Frits van Bommel Wrote:

> The last sentence of 
> http://www.digitalmars.com/d/1.0/expression.html#ShiftExpression : "It's 
> illegal to shift by more bits than the size of the quantity being shifted"
> That means that if you shift by more bits than the type can hold you 
> can't rely on the result. (And the compiler may in fact even refuse to 
> compile it)
> cast(long) works around this issue by upping the number of bits, but the 
> problem may recur if more than 64 bits are used (and it most likely 
> *will* on x86-64 systems, but I'm not sure how DMDs 'software longs' 
> handle that case)
> 
> It looks like the const-folding code in the compiler handles oversized 
> shifts differently than the machine code generated. (I can only 
> reproduce your problem by adding '-O' to the command line, without 
> optimizations the result is the same for q and v, and both shifts are 
> performed modulo 32)

Interesting.


> I can't say it's much of a surprise that the run-time shifted (v >> 48) 
> is done modulo 32, since that's exactly how the x86 'shr' opcode works. 
> Apparently the const-folding code performs the shift in a more intuitive 
> way, perhaps by storing integral and pointer constants in longs or just 
> by a runtime check on whether the amount shifted is too large...

I didn't know that.  I don't think the other processors I've used (years ago, when I first learned bit-shiftig) worked that way.  Interesting.

This came up because I was porting someone else's code.  Now I understand why it looked like this in C:
  (long)((long long)(long)v >> 48)

Very, very helpful reply.  Thank you!



More information about the Digitalmars-d mailing list