September 13, 2021
On Monday, 13 September 2021 at 16:00:35 UTC, Paul Backus wrote:
> On Monday, 13 September 2021 at 15:38:44 UTC, H. S. Teoh wrote:
>>
>> The integer promotion situation in D is a mess.  My personal preference is:
>>
>> --------
>> module nopromote;
>>
>> [...]
>
> Have you considered putting this up on code.dlang.org? Probably easier for people to find it there than by searching through old forum posts.

Looks like a different implementation, but there's https://code.dlang.org/packages/nopromote
September 13, 2021

On 9/13/21 11:38 AM, H. S. Teoh wrote:

>

On Sun, Sep 12, 2021 at 10:14:03AM -0400, Steven Schveighoffer via Digitalmars-d wrote:
[...]

>
onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
'-preview=intpromote' switch or `~cast(int)(x)`
onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
'-preview=intpromote' switch or `~cast(int)(x)`
Number of affected cases: 0

[...]

The integer promotion situation in D is a mess. My personal preference
is:


module nopromote;

Sure, just like everyone uses std.utf.byCodeUnit to avoid autodecoding, right?

-Steve

September 13, 2021
On Mon, Sep 13, 2021 at 01:49:25PM -0400, Steven Schveighoffer via Digitalmars-d wrote:
> On 9/13/21 11:38 AM, H. S. Teoh wrote:
> > On Sun, Sep 12, 2021 at 10:14:03AM -0400, Steven Schveighoffer via Digitalmars-d wrote: [...]
> > > ```
> > > onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
> > > '-preview=intpromote' switch or `~cast(int)(x)`
> > > onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
> > > '-preview=intpromote' switch or `~cast(int)(x)`
> > > Number of affected cases: 0
> > > ```
> > [...]
> > 
> > The integer promotion situation in D is a mess.  My personal preference is:
> > 
> > --------
> > module nopromote;
> 
> Sure, just like *everyone* uses std.utf.byCodeUnit to avoid autodecoding, right?
[...]

It's a solution (or half-solution hack) that works today, as opposed to a wishful solution that may or may not happen in the future, if ever.


T

-- 
Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
September 13, 2021

On 9/13/21 1:54 PM, H. S. Teoh wrote:

>

On Mon, Sep 13, 2021 at 01:49:25PM -0400, Steven Schveighoffer via Digitalmars-d wrote:

>

On 9/13/21 11:38 AM, H. S. Teoh wrote:

>

On Sun, Sep 12, 2021 at 10:14:03AM -0400, Steven Schveighoffer via Digitalmars-d wrote:
[...]

>
onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
'-preview=intpromote' switch or `~cast(int)(x)`
onlineapp.d(11): Deprecation: integral promotion not done for `~x`, use
'-preview=intpromote' switch or `~cast(int)(x)`
Number of affected cases: 0

[...]

The integer promotion situation in D is a mess. My personal
preference is:


module nopromote;

Sure, just like everyone uses std.utf.byCodeUnit to avoid
autodecoding, right?
[...]

It's a solution (or half-solution hack) that works today, as opposed to
a wishful solution that may or may not happen in the future, if ever.

We have intpromote queued to go into the language. But it's even worse than the current status quo.

If we are going to change the rules, we might as well change them to be better (at least do what the user expects). That's all I'm saying. We don't need more hacks that almost nobody will use.

Sorry to be blunt, but the problem with such things is that it gives an excuse to allow the horror show to continue "if you don't like it, you can just use this library!"

-Steve

September 13, 2021
On Mon, Sep 13, 2021 at 02:05:39PM -0400, Steven Schveighoffer via Digitalmars-d wrote: [...]
> We have intpromote queued to go into the language. But it's even worse than the current status quo.

I agree.


> If we are going to change the rules, we might as well change them to be better (at least do what the user expects). That's all I'm saying. We don't need more hacks that almost nobody will use.
> 
> Sorry to be blunt, but the problem with such things is that it gives an excuse to allow the horror show to continue "if you don't like it, you can just use this library!"
[...]

You're welcome to push for change.  I'll even support you.

But currently I'm not holding out much hope that intpromote will turn out for the better.  From what I've seen of it (and this thread proves it), it will be a disaster.  This isn't the first time complaints about intpromote came up.  But since Walter seems dead-set on pushing it through, it will probably get through anyway.  At least D still lets you use hacks like nopromote.d to shove the problem under the rug.


T

-- 
All problems are easy in retrospect.
September 13, 2021
On 9/13/2021 4:42 AM, Steven Schveighoffer wrote:
> C allows exactly what he wrote, and it already works the same as it does in C.

Allowing it is one thing, behaving the same is another.

I found the problem *because* a difference in behavior popped up.

September 13, 2021

On 9/13/21 3:55 PM, Walter Bright wrote:

>

On 9/13/2021 4:42 AM, Steven Schveighoffer wrote:

>

C allows exactly what he wrote, and it already works the same as it does in C.

Allowing it is one thing, behaving the same is another.

I found the problem because a difference in behavior popped up.

The behavior is the same in this case. When you flip the bits in a ushort and assign to another ushort, you don't care about the behavior of the other bits at all.

To reiterate, intpromote is going to require lots of casts, most of which wouldn't change any behavior that is currently happening.

The cases where the behavior is different is going from 8 or 16-bit integers to higher bit numbers. IMO, intpromote should focus on those, and leave the others alone.

I agree that the following is nonsense, and C gets it right.

ushort x = 500;
int y = -x;
assert(y == 65036);

But fixing this problem doesn't mean we have to break all existing code for the purpose of busywork to insert casts to achieve the current behavior.

I just realized, the deprecation doesn't even say how to replicate current behavior. It says to cast to int before applying the operator, but that's not what current behavior does, it's what the new behavior does. Typically, deprecations identify how to adjust your code so it continues to do the same thing. This does the opposite.

-Steve

September 13, 2021

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

>

With the -preview=intpromote switch, the uncasted negation compiles and runs as expected.

Right now, the deprecation is telling users under penalty of not compiling to do something that will achieve nothing when intpromote is enabled.

What is achieve is that people can review the place where -x and ~x were used, and see if there was bug there ; because it is a real possibility that C code was ported and then it has a different semantics.

The end game of it is:

A. "when you paste C code and it builds then it's the same"

instead of:

B. "when you paste C code and it builds then it's the same, EXCEPT -x and ~x who don't promote their operand to int"

when people of the future come to D in 2030 they will enjoy the proposition A instead of B.

September 13, 2021

On 9/13/21 5:03 PM, Guillaume Piolat wrote:

>

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

>

With the -preview=intpromote switch, the uncasted negation compiles and runs as expected.

Right now, the deprecation is telling users under penalty of not compiling to do something that will achieve nothing when intpromote is enabled.

What is achieve is that people can review the place where -x and ~x were used, and see if there was bug there ; because it is a real possibility that C code was ported and then it has a different semantics.

Why should I review all uses, when the compiler can trivially prove it's fine for most of them, and warn on the cases that will need attention? It already doesn't warn for ~int or -int, so it's not just usage of that operator that is problematic, but specific uses.

Note that D already does the right thing for all the code I've pointed out here.

>

The end game of it is:

   A. "when you paste C code and it builds then it's the same"

instead of:

   B. "when you paste C code and it builds then it's the same, EXCEPT -x and ~x who don't promote their operand to int"

C allows assigning ints to shorts. When you have:

short x = -y;

It's exactly the same as C. There's no reason to deprecate this. When you build without using intpromote, it does what C does. When you build using intpromote, you have to cast to a short, which.... does what C does.

>

when people of the future come to D in 2030 they will enjoy the proposition A instead of B.

It all depends on if your opinion is that when you paste C code, it shouldn't compile. Because basically that's what's happening here.

D gets away with requiring a cast here or there without being annoying, because VRP takes care of many cases, and op= cases work even though the written out form would not. But that won't be true here, and I can say there's probably a decent chunk of bit manipulation with ushorts.

I'd propose that:

  1. In cases where the behavior is already the same as C, and would not require casts after intpromote is enabled, do not warn.
  2. In cases where a type is being assigned to the negation of the same type, do not require a cast, and do not warn.
  3. In cases where the behavior is NOT the same as C, issue a warning and corrective action recommendation (i.e. either ~cast(int)(val) to get rid of the warning and accept new behavior, or cast(ushort)~(val) to keep existing behavior).

I honestly don't think casts should be necessary anywhere they aren't already required after intpromote is enabled.

This would achieve your goal (warn people so they can inspect problematic cases) without ruining most valid code.

-Steve

September 13, 2021

On Monday, 13 September 2021 at 21:03:41 UTC, Guillaume Piolat wrote:

>

On Sunday, 12 September 2021 at 14:14:03 UTC, Steven Schveighoffer wrote:

It's also not exactly clear why:

  1. D should be backward compatible with C, which is 50 years old soon.
  2. why exactly somebody should copy / paste (how many? thousands?) many lines of code without thinking and rechecking. Probably D can't be and shouldn't be compatible with C / C++ to that distinct.
  3. Is really backward comparability with C/C++ so important?