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...