Re: New integer promotion rules

2021-01-01 Thread Paul via Digitalmars-d-learn

On Thursday, 18 January 2018 at 16:31:02 UTC, ag0aep6g wrote:
I'm interpreting that to mean that it will become an error for 
some time, but later it will be allowed again with the new 
behavior. And then you can throw away `-transition=intpromote`.


Seeing as it's almost 3 years later, I'd like to ask, is there an 
indication of when this will happen? It seems to still be around.


Re: New integer promotion rules

2018-01-18 Thread rumbu via Digitalmars-d-learn

On Thursday, 18 January 2018 at 18:00:51 UTC, rumbu wrote:

On Thursday, 18 January 2018 at 17:54:59 UTC, rumbu wrote:

On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes




target = isNegative ? cast(Unsigned!T)(-c) : 
cast(Unsigned!T)c;


That would have been better even before the change, because 
the operator '-' used on unsigned types is likely to produce 
unexpected results, if the behaviour is defined at all.


I don't think so:

ulong c = 128;
bool isNegative = true;
byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c;

Error Deprecation: integral promotion not done for 
`-cast(ubyte)c`, use '-transition=intpromote' switch or 
`-cast(int)(cast(ubyte)c)`		


My bad, it works. Thanks:

ulong c = 128;
bool isNegative = true;
byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c;


But this doesn't:

ushort c = 128;
bool isNegative = true;
byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c;

Error Deprecation: integral promotion not done for `-c`, use 
'-transition=intpromote' switch or `-cast(int)(c)


This is starting to become truly crazy.




Re: New integer promotion rules

2018-01-18 Thread rumbu via Digitalmars-d-learn

On Thursday, 18 January 2018 at 17:54:59 UTC, rumbu wrote:

On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes




target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c;

That would have been better even before the change, because 
the operator '-' used on unsigned types is likely to produce 
unexpected results, if the behaviour is defined at all.


I don't think so:

ulong c = 128;
bool isNegative = true;
byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c;

Error Deprecation: integral promotion not done for 
`-cast(ubyte)c`, use '-transition=intpromote' switch or 
`-cast(int)(cast(ubyte)c)`		


My bad, it works. Thanks:

ulong c = 128;
bool isNegative = true;
byte target = isNegative ? cast(ubyte)-c : cast(ubyte)c;


Re: New integer promotion rules

2018-01-18 Thread rumbu via Digitalmars-d-learn
On Thursday, 18 January 2018 at 12:51:48 UTC, Dominikus Dittes 
Scherkl wrote:

On Thursday, 18 January 2018 at 06:05:08 UTC, rumbu wrote:

On Thursday, 18 January 2018 at 02:30:17 UTC, Rubn wrote:

On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote:

code like "m = n < 0 ? -n : n" doesn't worth a wrapper


That code is worth a wrapper, it's called "abs"...

m = abs(n);


Well, since I'm in the learn forum and you seem to have a 
response to anything, can you help me translate this line 
under the new integer promotion rules?


https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L7804

Thanks.


target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c;

That would have been better even before the change, because the 
operator '-' used on unsigned types is likely to produce 
unexpected results, if the behaviour is defined at all.


I don't think so:

ulong c = 128;
bool isNegative = true;
byte target = isNegative ? -cast(ubyte)c : cast(ubyte)c;

Error Deprecation: integral promotion not done for 
`-cast(ubyte)c`, use '-transition=intpromote' switch or 
`-cast(int)(cast(ubyte)c)`		


Re: New integer promotion rules

2018-01-18 Thread ag0aep6g via Digitalmars-d-learn

On 01/18/2018 05:22 PM, Steven Schveighoffer wrote:
Sure, but what does the statement "Once deprecated this will become an 
error" mean? Will I have to use the -transition=intpromote switch 
forever to avoid an error?


As you quoted before: "Once deprecated this will become an error, and 
then the C-like behavior will become the default."


I'm interpreting that to mean that it will become an error for some 
time, but later it will be allowed again with the new behavior. And then 
you can throw away `-transition=intpromote`.


Re: New integer promotion rules

2018-01-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/18/18 11:14 AM, ag0aep6g wrote:

On 01/18/2018 03:30 PM, Steven Schveighoffer wrote:
Is there going to be a point where casts aren't needed? Otherwise, 
this is pretty ugly.


You don't need casts when you use `-transition=intpromote`.


Sure, but what does the statement "Once deprecated this will become an 
error" mean? Will I have to use the -transition=intpromote switch 
forever to avoid an error?


Thinking about the fact that the deprecation doesn't show an error for 
the -transition switch, makes me think possibly the changelog message is 
incorrect.


-Steve


Re: New integer promotion rules

2018-01-18 Thread ag0aep6g via Digitalmars-d-learn

On 01/18/2018 03:30 PM, Steven Schveighoffer wrote:
Is there going to be a point where casts aren't needed? Otherwise, this 
is pretty ugly.


You don't need casts when you use `-transition=intpromote`.


Re: New integer promotion rules

2018-01-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/17/18 2:40 PM, rumbu wrote:

This started in the last DMD version (2.078):

byte b = -10;
ulong u = b < 0 ? -b : b;

//Deprecation: integral promotion not done for `-b`, use 
'-transition=intpromote' switch or `-cast(int)(b)


Why do I need a to promote a byte to int to obtain an ulong? Even in the 
extreme case where b is byte.min, -byte.min as unsigned is exactly what 
i need: 128;


This leads to more cases:

ubyte u = cast(ubyte)-b;
//Deprecation: integral promotion not done for `-b`, use 
'-transition=intpromote' switch or `-cast(int)(b)`


Last time I checked, casting is somehow synonym with "I know what I'm 
doing", why do I need another cast to prove my sanity: ubyte u = 
cast(ubyte)-cast(int)b;


I was going to respond with a helpful guide on what to do here, but I 
either misunderstand the docs, or I don't agree with the transition 
requirements.


I thought that you could simply ignore this deprecation message if it 
doesn't affect you (i.e. you don't have the possibility of seeing the 
corner cases that are fixed), but looking at the changelog it says:


"Once deprecated this will become an error, and then the C-like behavior 
will become the default."


So this says, even if you aren't affected, you *still* have to add casts 
to avoid a future error? I thought it was going to be deprecated, and 
then after some number of versions it would just be switched to the new 
behavior.


Is there going to be a point where casts aren't needed? Otherwise, this 
is pretty ugly.


-Steve


Re: New integer promotion rules

2018-01-18 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn

On Thursday, 18 January 2018 at 06:05:08 UTC, rumbu wrote:

On Thursday, 18 January 2018 at 02:30:17 UTC, Rubn wrote:

On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote:

code like "m = n < 0 ? -n : n" doesn't worth a wrapper


That code is worth a wrapper, it's called "abs"...

m = abs(n);


Well, since I'm in the learn forum and you seem to have a 
response to anything, can you help me translate this line under 
the new integer promotion rules?


https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L7804

Thanks.


target = isNegative ? cast(Unsigned!T)(-c) : cast(Unsigned!T)c;

That would have been better even before the change, because the 
operator '-' used on unsigned types is likely to produce 
unexpected results, if the behaviour is defined at all.


Re: New integer promotion rules

2018-01-17 Thread rumbu via Digitalmars-d-learn

On Thursday, 18 January 2018 at 02:30:17 UTC, Rubn wrote:

On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote:

code like "m = n < 0 ? -n : n" doesn't worth a wrapper


That code is worth a wrapper, it's called "abs"...

m = abs(n);


Well, since I'm in the learn forum and you seem to have a 
response to anything, can you help me translate this line under 
the new integer promotion rules?


https://github.com/rumbu13/decimal/blob/master/src/decimal/decimal.d#L7804

Thanks.


Re: New integer promotion rules

2018-01-17 Thread Rubn via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote:

code like "m = n < 0 ? -n : n" doesn't worth a wrapper


That code is worth a wrapper, it's called "abs"...

m = abs(n);




Re: New integer promotion rules

2018-01-17 Thread ag0aep6g via Digitalmars-d-learn

On 01/17/2018 11:30 PM, rumbu wrote:
1. Why do I need explicitely to promote my byte to int in order to 
assign it to an ulong?

2.077: ulong u = -b; 2.088: ulong u = -cast(int)b;


Those two snippets are not equivalent.

When b = byte.min, the 2.077 snippet gives u = 18446744073709551488, 
while the 2.078 snippet gives u = 128 even when compiled with 2.077.


Old code may rely on u = 18446744073709551488, and that's why dmd 2.078 
doesn't just silently give you 128. Instead you have to use the cast or 
the compiler switch to tell dmd that you actually want the new behavior. 
In the future, the new behavior is going to become the default.


You have to be explicit about this so that dmd doesn't break your code 
without you noticing.


2. Why do I need a cast(int) to assign a byte to an ubyte, since I'm 
explicitely cast it?

2.077: ubyte c = cast(ubyte)-b; 2.088: ubyte c = cast(ubyte)-cast(int)b


As above, when b = byte(-128), then `-b` is going to change from 
byte(-128) to int(128). In this case, that doesn't affect the result, 
because `cast(ubyte) byte(-128)` and `cast(ubyte) int(128)` are both 
128. But the compiler obviously doesn't look that far. And it's not 
possible for the compiler to analyse the whole program before giving you 
the deprecation message.


Re: New integer promotion rules

2018-01-17 Thread Ali Çehreli via Digitalmars-d-learn

On 01/17/2018 02:30 PM, rumbu wrote:

> 1. Why do I need explicitely to promote my byte to int in order to
> assign it to an ulong?
> 2.077: ulong u = -b; 2.088: ulong u = -cast(int)b;

You're not assigning your byte to ulong; you're assigning the expression 
-b to ulong. -b is discovered to have unintended behavior, which is now 
fixed. We have to go throught a transition period not to break old code 
that may have depended on the old unintended behavior.


> 2. Why do I need a cast(int) to assign a byte to an ubyte, since I'm
> explicitely cast it?
> 2.077: ubyte c = cast(ubyte)-b; 2.088: ubyte c = cast(ubyte)-cast(int)b

Same issue: the question is about what -b means before your cast in the 
2.077 version of the code.


Ali



Re: New integer promotion rules

2018-01-17 Thread rumbu via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 21:12:07 UTC, Rubn wrote:

On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote:

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max);


The generic code above (which worked for all signed integral 
types T in 2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
   auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
   auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my 
project.


Or write some wrapper code, which you prob should have done in 
the first place if you use that all around your project:


auto max = myMaxFunc!(isNegative, T);


"max" was just an over-templated example to highlight the 
problem, code like "m = n < 0 ? -n : n" doesn't worth a wrapper, 
for example.


But the original questions remain:

1. Why do I need explicitely to promote my byte to int in order 
to assign it to an ulong?

2.077: ulong u = -b; 2.088: ulong u = -cast(int)b;

2. Why do I need a cast(int) to assign a byte to an ubyte, since 
I'm explicitely cast it?
2.077: ubyte c = cast(ubyte)-b; 2.088: ubyte c = 
cast(ubyte)-cast(int)b







Re: New integer promotion rules

2018-01-17 Thread Rubn via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote:

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max);


The generic code above (which worked for all signed integral 
types T in 2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
   auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
   auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my 
project.


Or write some wrapper code, which you prob should have done in 
the first place if you use that all around your project:


auto max = myMaxFunc!(isNegative, T);


Re: New integer promotion rules

2018-01-17 Thread ag0aep6g via Digitalmars-d-learn

On 01/17/2018 09:30 PM, rumbu wrote:

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max);

The generic code above (which worked for all signed integral types T in 
2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
    auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
    auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my project.


So here you prefer the old behavior.

But in your previous post you wrote:


compiled with 2.077 or 2.078 with -transition=intpromote

byte b = byte.min;
ulong u = -b;
writeln(u);

outputs correctly 128 


And that's the new behavior.

You can't have both. You either get to keep the shorter version of your 
max code, or you get "correct" results on `ulong u = -b;`.


Except you can actually (almost) keep your max code, as far as I see. 
Under the old rules `-T.min` is just `T.min` again. So you can just drop 
the negation there and get the same result. And then it works under the 
new rules too, because there's no negation involved.


I.e.: auto max = isNegative ? cast(Unsigned!T)(T.min) : 
cast(Unsigned!T)T.max;


Re: New integer promotion rules

2018-01-17 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote:

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max);


The generic code above (which worked for all signed integral 
types T in 2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
   auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
   auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my 
project.


Yes i know. In a way i agree but in another i've accepted the 
thing, that's why for example there's:


https://github.com/dlang/phobos/pull/5958/files

I had to do similar things in my own stuff.
Other people had to as well.

In my stuff i've used

  `cast(ubyte) (stuff * -1)`

instead of

  `-stuff`

because i've verified that in both cases an asm NEG is generated.

But well, i understand your concern ;)


Re: New integer promotion rules

2018-01-17 Thread rumbu via Digitalmars-d-learn

And here is why is bothering me:

auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max);


The generic code above (which worked for all signed integral 
types T in 2.077) must be rewritten like this in 2.078:


static if (T.sizeof >= 4)
   auto max = isNegative ? cast(Unsigned!T)(-T.min) : 
cast(Unsigned!T)T.max;

else
   auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : 
cast(Unsigned!T)T.max;


Now I have to translate an 1-liner in a 4-liner all around my 
project.






Re: New integer promotion rules

2018-01-17 Thread rumbu via Digitalmars-d-learn

On Wednesday, 17 January 2018 at 19:54:50 UTC, ag0aep6g wrote:

On 01/17/2018 08:40 PM, rumbu wrote:

This started in the last DMD version (2.078):

byte b = -10;
ulong u = b < 0 ? -b : b;

//Deprecation: integral promotion not done for `-b`, use 
'-transition=intpromote' switch or `-cast(int)(b)


Why do I need a to promote a byte to int to obtain an ulong? 
Even in the extreme case where b is byte.min, -byte.min as 
unsigned is exactly what i need: 128;


Actually, for b = byte.min, you get u = 18446744073709551488.


Wrong, compiled with 2.077 or 2.078 with -transition=intpromote

byte b = byte.min;
ulong u = -b;
writeln(u);

outputs correctly 128



2.078 is starting to fix this so that you get 128. But that's a 
breaking change, so you have to use the compiler switch or the 
cast for a couple releases.


In the changelog: 
https://dlang.org/changelog/2.078.0.html#fix16997





Re: New integer promotion rules

2018-01-17 Thread ag0aep6g via Digitalmars-d-learn

On 01/17/2018 08:40 PM, rumbu wrote:

This started in the last DMD version (2.078):

byte b = -10;
ulong u = b < 0 ? -b : b;

//Deprecation: integral promotion not done for `-b`, use 
'-transition=intpromote' switch or `-cast(int)(b)


Why do I need a to promote a byte to int to obtain an ulong? Even in the 
extreme case where b is byte.min, -byte.min as unsigned is exactly what 
i need: 128;


Actually, for b = byte.min, you get u = 18446744073709551488.

2.078 is starting to fix this so that you get 128. But that's a breaking 
change, so you have to use the compiler switch or the cast for a couple 
releases.


In the changelog: https://dlang.org/changelog/2.078.0.html#fix16997