Jonathan M Davis wrote:
On Tuesday 09 August 2011 09:32:41 Don wrote:
Jonathan M Davis wrote:
On Monday 08 August 2011 00:33:31 Dmitry Olshansky wrote:
Just lost the best part of an hour figuring the cause of this small
problem, consider:

void main()
{

         uint j = 42;
         ulong k = 1<<cast(ulong)j;
         ulong m = 1UL<<j;
         assert(k == 1024);//both asserts do pass
         assert(m == (1UL<<42));

}

I though left operand should be promoted to the largest integer in
shift
expression, isn't it?
I would not expect that type of integer being used to give the number of
bits to shift to affect thet type of integer being shifted. It doesn't
generally make much sense to shift more than the size of the integer
type being shifted, and that can always fit in a byte. So, why would
the type of the integer being used to give the number of bits to shift
matter? It's like an index. The index doesn't affect the type of what's
being indexed. It just gives you an index.

You have to deal with integer promotions and all that when doing
arithmetic, because arithmetic needs to be done with a like number of
bits on both sides of the operation. But with shifting, all your doing
is asking it to shift some number of bits. The type which holds the
number of bits shouldn't really matter. I wouldn't expect _any_ integer
promotions to occur in a shift expression. If you want to affect what's
being shifted, then cast what's being shifted.
Your intuition is wrong!

expression.html explicitly states the operands to shifts undergo
integral promotions. But they don't get arithmetic conversions.

I think this is terrible.

short x = -1;
x >>>= 1;

Guess what x is...

That's just downright weird. Why would any integral promotions occur with a shift? And given your example, the current behavior seems like a bad design. Is this some weird hold-over from C/C++?

I think it must be, some silly idea of 'simplifying' things by applying the same promotion rules to all binary operators. Given that 256-bit integers still don't seem to be coming any time soon, even shifts by a signed byte shouldn't require promotion. Incidentally, the x86 instruction set doesn't use integers, you can only shift a 64-bit number by an 8-bit value. So x << y always compiles to
x << cast(ubyte)y. Shift should not need a common type.

This is one of those things that can cause problems, but never helps.

Reply via email to