Thread overview
Why isn't the overflow flag set?
Nov 10, 2011
Simen Kjærås
Nov 10, 2011
Simen Kjærås
Nov 11, 2011
Simon
Nov 11, 2011
Simen Kjærås
Nov 10, 2011
Timon Gehr
November 10, 2011
I'm creating a Checked!T struct for integral values. The version attached
works
for the most part, but some parts confuse me, namely that the following
operations do not set the overflow flag:

uint.max + 1
ulong.max + 1

int.min - 1
uint.min - 1
long.min - 1
ulong.min - 1

uint.max << 1
long.max << 1
ulong.max << 1

int.min << 1
long.min << 1

int a = int.max; a *= 2
long a = long.max; a *= 2

The following feel wrong to me, but I guess there may be reasons behind them:

ubyte a = ubyte.min; --a
ushort a = ushort.min; --a
uint a = uint.min; --a
ulong a = ulong.min; --a

ubyte a = ubyte.max; ++a
ushort a = ushort.max; ++a
uint a = uint.max; ++a
ulong a = ulong.max; ++a

ubyte a = ubyte.max; a *= 2
ushort a = ushort.max; a *= 2
uint a = uint.max; a *= 2
ulong a = ulong.max; a *= 2

ubyte a = ubyte.min; a -= 1
ushort a = ushort.min; a -= 1
uint a = uint.min; a -= 1
ulong a = ulong.min; a -= 1

ubyte a = ubyte.max; a <<= 1
ushort a = ushort.max; a <<= 1
uint a = uint.max; a <<= 1
ulong a = ulong.max; a <<= 1

Are some of these supposed to work but don't?

November 10, 2011
On Thu, 10 Nov 2011 12:24:30 -0500, Simen Kjærås <simen.kjaras@gmail.com> wrote:

> I'm creating a Checked!T struct for integral values. The version attached
> works
> for the most part, but some parts confuse me, namely that the following
> operations do not set the overflow flag:
>
> uint.max + 1
> ulong.max + 1
>
> int.min - 1
> uint.min - 1
> long.min - 1
> ulong.min - 1
>
> uint.max << 1
> long.max << 1
> ulong.max << 1
>
> int.min << 1
> long.min << 1

These are likely folded into a single constant.  I think it would be inappropriate for these to set the flag (it would be something unnatural anyways).

>
> int a = int.max; a *= 2
> long a = long.max; a *= 2

These I would think could set the overflow flag, but not necessarily when optimized.

I suspect in order to prevent optimization, you may have to do the operations using asm.  Which would be difficult to do (to say the least) using a template parameter.

-Steve
November 10, 2011
On Thu, 10 Nov 2011 18:56:37 +0100, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> On Thu, 10 Nov 2011 12:24:30 -0500, Simen Kjærås <simen.kjaras@gmail.com> wrote:
>
>> I'm creating a Checked!T struct for integral values. The version attached
>> works
>> for the most part, but some parts confuse me, namely that the following
>> operations do not set the overflow flag:
>>
>> uint.max + 1
>> ulong.max + 1
>>
>> int.min - 1
>> uint.min - 1
>> long.min - 1
>> ulong.min - 1
>>
>> uint.max << 1
>> long.max << 1
>> ulong.max << 1
>>
>> int.min << 1
>> long.min << 1
>
> These are likely folded into a single constant.  I think it would be inappropriate for these to set the flag (it would be something unnatural anyways).

Sorry, my example was simplified. These are all on the form

uint a = uint.max;
a = a + 1;

It works for all integral types not mentioned here.


>> int a = int.max; a *= 2
>> long a = long.max; a *= 2
>
> These I would think could set the overflow flag, but not necessarily when optimized.

No optimizations are on, and -debug is passed. I find it unlikely the
compiler is doing much magic here. If it does, I am more than willing
to call it a bug.
November 10, 2011
On 11/10/2011 06:24 PM, Simen Kjærås wrote:
> I'm creating a Checked!T struct for integral values. The version
> attached works
> for the most part, but some parts confuse me, namely that the following
> operations do not set the overflow flag:
>
> uint.max + 1
> ulong.max + 1
>
> int.min - 1
> uint.min - 1
> long.min - 1
> ulong.min - 1
>
> uint.max << 1
> long.max << 1
> ulong.max << 1
>
> int.min << 1
> long.min << 1
>
> int a = int.max; a *= 2
> long a = long.max; a *= 2
>
> The following feel wrong to me, but I guess there may be reasons behind
> them:
>
> ubyte a = ubyte.min; --a
> ushort a = ushort.min; --a
> uint a = uint.min; --a
> ulong a = ulong.min; --a
>
> ubyte a = ubyte.max; ++a
> ushort a = ushort.max; ++a
> uint a = uint.max; ++a
> ulong a = ulong.max; ++a
>
> ubyte a = ubyte.max; a *= 2
> ushort a = ushort.max; a *= 2
> uint a = uint.max; a *= 2
> ulong a = ulong.max; a *= 2
>
> ubyte a = ubyte.min; a -= 1
> ushort a = ushort.min; a -= 1
> uint a = uint.min; a -= 1
> ulong a = ulong.min; a -= 1
>
> ubyte a = ubyte.max; a <<= 1
> ushort a = ushort.max; a <<= 1
> uint a = uint.max; a <<= 1
> ulong a = ulong.max; a <<= 1
>
> Are some of these supposed to work but don't?

The overflow flag indicates that a signed overflow has occurred. To test for unsigned overflow, check the carry flag with jc.

November 11, 2011
On 10/11/2011 18:46, Simen Kjærås wrote:
> On Thu, 10 Nov 2011 18:56:37 +0100, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>
>> On Thu, 10 Nov 2011 12:24:30 -0500, Simen Kjærås
>> <simen.kjaras@gmail.com> wrote:
>>
>>> I'm creating a Checked!T struct for integral values. The version
>>> attached
>>> works
>>> for the most part, but some parts confuse me, namely that the following
>>> operations do not set the overflow flag:
>>>
>>> uint.max + 1
>>> ulong.max + 1
>>>
>>> int.min - 1
>>> uint.min - 1
>>> long.min - 1
>>> ulong.min - 1
>>>
>>> uint.max << 1
>>> long.max << 1
>>> ulong.max << 1
>>>
>>> int.min << 1
>>> long.min << 1
>>
>> These are likely folded into a single constant. I think it would be
>> inappropriate for these to set the flag (it would be something
>> unnatural anyways).
>
> Sorry, my example was simplified. These are all on the form
>
> uint a = uint.max;
> a = a + 1;
>
> It works for all integral types not mentioned here.
>
>
>>> int a = int.max; a *= 2
>>> long a = long.max; a *= 2
>>
>> These I would think could set the overflow flag, but not necessarily
>> when optimized.
>
> No optimizations are on, and -debug is passed. I find it unlikely the
> compiler is doing much magic here. If it does, I am more than willing
> to call it a bug.

Don't know if it's changed but the last time I looked at the compiler, it still does constant folding even in debug mode.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
November 11, 2011
On Fri, 11 Nov 2011 19:19:03 +0100, Simon <s.d.hammett@gmail.com> wrote:

> On 10/11/2011 18:46, Simen Kjærås wrote:
>> On Thu, 10 Nov 2011 18:56:37 +0100, Steven Schveighoffer
>> <schveiguy@yahoo.com> wrote:
>>
>>> On Thu, 10 Nov 2011 12:24:30 -0500, Simen Kjærås
>>> <simen.kjaras@gmail.com> wrote:
>>>
>>>> I'm creating a Checked!T struct for integral values. The version
>>>> attached
>>>> works
>>>> for the most part, but some parts confuse me, namely that the following
>>>> operations do not set the overflow flag:
>>>>
>>>> uint.max + 1
>>>> ulong.max + 1
>>>>
>>>> int.min - 1
>>>> uint.min - 1
>>>> long.min - 1
>>>> ulong.min - 1
>>>>
>>>> uint.max << 1
>>>> long.max << 1
>>>> ulong.max << 1
>>>>
>>>> int.min << 1
>>>> long.min << 1
>>>
>>> These are likely folded into a single constant. I think it would be
>>> inappropriate for these to set the flag (it would be something
>>> unnatural anyways).
>>
>> Sorry, my example was simplified. These are all on the form
>>
>> uint a = uint.max;
>> a = a + 1;
>>
>> It works for all integral types not mentioned here.
>>
>>
>>>> int a = int.max; a *= 2
>>>> long a = long.max; a *= 2
>>>
>>> These I would think could set the overflow flag, but not necessarily
>>> when optimized.
>>
>> No optimizations are on, and -debug is passed. I find it unlikely the
>> compiler is doing much magic here. If it does, I am more than willing
>> to call it a bug.
>
> Don't know if it's changed but the last time I looked at the compiler, it still does constant folding even in debug mode.

That may be, but these are not folded, at least not for the types not
mentioned above.