(int << ulong) == int ?

Don nospam at nospam.com
Tue Aug 9 02:03:11 PDT 2011


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.



More information about the Digitalmars-d-learn mailing list