Thread overview
Bit operator conversions
Apr 06, 2009
Kagamin
Apr 07, 2009
Sergey Gromov
Apr 08, 2009
Kagamin
Apr 08, 2009
Sergey Gromov
Apr 09, 2009
Don
April 06, 2009
Is it valid for this to compile:
---
ushort a(ushort b) pure nothrow
	{ return b<<10|b; }
---

And for this to not compile:
---
ushort a(ushort b) pure nothrow
	{ return b<<10; }
---
?
April 07, 2009
Mon, 06 Apr 2009 08:53:41 -0400, Kagamin wrote:

> Is it valid for this to compile:
> ---
> ushort a(ushort b) pure nothrow
> 	{ return b<<10|b; }
> ---
> 
> And for this to not compile:
> ---
> ushort a(ushort b) pure nothrow
> 	{ return b<<10; }
> ---
> ?

They both compile with 2.026.  What's your problem?
April 08, 2009
Sergey Gromov Wrote:

> Mon, 06 Apr 2009 08:53:41 -0400, Kagamin wrote:
> 
> > Is it valid for this to compile:
> > ---
> > ushort a(ushort b) pure nothrow
> > 	{ return b<<10|b; }
> > ---
> > 
> > And for this to not compile:
> > ---
> > ushort a(ushort b) pure nothrow
> > 	{ return b<<10; }
> > ---
> > ?
> 
> They both compile with 2.026.  What's your problem?

Could you please check bug http://d.puremagic.com/issues/show_bug.cgi?id=2809 with your dmd 2.026? It can be regression.
April 08, 2009
Wed, 08 Apr 2009 12:06:48 -0400, Kagamin wrote:

> Sergey Gromov Wrote:
> 
>> Mon, 06 Apr 2009 08:53:41 -0400, Kagamin wrote:
>> 
>>> Is it valid for this to compile:
>>> ---
>>> ushort a(ushort b) pure nothrow
>>> 	{ return b<<10|b; }
>>> ---
>>> 
>>> And for this to not compile:
>>> ---
>>> ushort a(ushort b) pure nothrow
>>> 	{ return b<<10; }
>>> ---
>>> ?
>> 
>> They both compile with 2.026.  What's your problem?
> 
> Could you please check bug http://d.puremagic.com/issues/show_bug.cgi?id=2809 with your dmd 2.026? It can be regression.

Yes the #2809 is present in 2.026.

Actually I didn't realize your example was meant to be compiled with -w switch.  Without -w it simply compiles, no problem.  With -w, it fails while I think it shouldn't.
April 08, 2009
On Mon, Apr 6, 2009 at 8:53 AM, Kagamin <spam@here.lot> wrote:
> Is it valid for this to compile:
> ---
> ushort a(ushort b) pure nothrow
>        { return b<<10|b; }
> ---
>
> And for this to not compile:
> ---
> ushort a(ushort b) pure nothrow
>        { return b<<10; }
> ---
> ?

There was a terribly long conversation about this and other operations here:

http://d.puremagic.com/issues/show_bug.cgi?id=1977

Basically the idea behind the warning on the left-shift is that you can't know, at compile-time, whether the shift will overflow the size of ushort or not.  If you passed in 0xFFFF, for instance, it would overflow.  So it converts left-shifts to int and complains if you don't have an explicit cast.

But for many bitwise operators, such as | and &, there is no risk of an overflow at runtime, so if your function returned "b & 0x3F00", you wouldn't get such a warning.

That it accepts "b << 10 | b" but rejects "b << 10", however, looks more like a bug.  It's like the compiler isn't doing enough work to find out whether the former can overflow or not.
April 09, 2009
Jarrett Billingsley wrote:
> On Mon, Apr 6, 2009 at 8:53 AM, Kagamin <spam@here.lot> wrote:
>> Is it valid for this to compile:
>> ---
>> ushort a(ushort b) pure nothrow
>>        { return b<<10|b; }
>> ---
>>
>> And for this to not compile:
>> ---
>> ushort a(ushort b) pure nothrow
>>        { return b<<10; }
>> ---
>> ?
> 
> There was a terribly long conversation about this and other operations here:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=1977
> 
> Basically the idea behind the warning on the left-shift is that you
> can't know, at compile-time, whether the shift will overflow the size
> of ushort or not.  If you passed in 0xFFFF, for instance, it would
> overflow.  So it converts left-shifts to int and complains if you
> don't have an explicit cast.
> 
> But for many bitwise operators, such as | and &, there is no risk of
> an overflow at runtime, so if your function returned "b & 0x3F00", you
> wouldn't get such a warning.
> 
> That it accepts "b << 10 | b" but rejects "b << 10", however, looks
> more like a bug.  It's like the compiler isn't doing enough work to
> find out whether the former can overflow or not.

cast.c line 50.

		/* This is really only a semi-kludge fix,
		 * we really should look at the operands of op
		 * and see if they are narrower types.
		 * For example, b=b|b and b=b|7 and s=b+b should be allowed,
		 * but b=b|i should be an error.
		 */

Sure, put it in bugzilla.