enforce (i > 0) for i = int.min does not throw

Steven Schveighoffer schveiguy at yahoo.com
Wed Jan 31 16:53:40 UTC 2018


On 1/30/18 3:37 PM, kdevel wrote:
> On Sunday, 28 January 2018 at 19:17:49 UTC, Steven Schveighoffer wrote:
>> This is insane. i > 0 is used in so many places. The only saving grace 
>> appears to be that int.min is just so uncommonly seen in the wild.
> 
> And another one that it does not happen when compiled with optimization 
> (-O) and also that it does not affect all the ints:
> 
> ---
> import std.stdio;
> 
> void foo (T) ()
> {
>     auto i = T.min;
>     writefln ("%12s: %24X %12s", T.stringof, i, i > cast(T) 0);
> }
> 
> void main ()
> {
>     foo!byte;
>     foo!short;
>     foo!int;
>     foo!long;
> }
> ---
> 
>          byte:                       80        false
>         short:                     8000        false
>           int:                 80000000         true
>          long:         8000000000000000         true
>

This is due to integer promotion 
(https://dlang.org/spec/type.html#usual-arithmetic-conversions). Any 
operation between two non-integers, first the two operands are promoted 
to integers.

You can see the result here:

https://run.dlang.io/is/RAk9tE

> In 32 bit mode:
> 
>          byte:                       80        false
>         short:                     8000        false
>           int:                 80000000         true
>          long:         8000000000000000        false
> 

Most likely, this is due to the fact that working with longs cannot be 
done natively by the CPU, so it can't use the same shifting shortcut 
that causes the issue in the first place.

-Steve


More information about the Digitalmars-d-learn mailing list