Jump to page: 1 2 3
Thread overview
April 30
ubyte a;
const(ubyte) b;

auto x = true ? a : b;

pragma(msg, typeof(x)); // int

Why? This isn't a VRP problem, as both are ubyte.

Related issue

https://issues.dlang.org/show_bug.cgi?id=19817

-Steve

April 30
On Tue, Apr 30, 2024 at 06:19:28PM +0000, Steven Schveighoffer via Digitalmars-d wrote:
> ```d
> ubyte a;
> const(ubyte) b;
> 
> auto x = true ? a : b;
> 
> pragma(msg, typeof(x)); // int
> ```
> 
> Why? This isn't a VRP problem, as both are `ubyte`.
> 
> Related issue
> 
> https://issues.dlang.org/show_bug.cgi?id=19817
[...]

Betcha it's something to do with integer promotion rules.


T

-- 
Just because you survived after you did it, doesn't mean it wasn't stupid!
April 30
On Tuesday, 30 April 2024 at 19:23:58 UTC, H. S. Teoh wrote:
> On Tue, Apr 30, 2024 at 06:19:28PM +0000, Steven Schveighoffer via Digitalmars-d wrote:
>> ```d
>> ubyte a;
>> const(ubyte) b;
>> 
>> auto x = true ? a : b;
>> 
>> pragma(msg, typeof(x)); // int
>> ```
>> 
>> Why? This isn't a VRP problem, as both are `ubyte`.
>> 
>> Related issue
>> 
>> https://issues.dlang.org/show_bug.cgi?id=19817
> [...]
>
> Betcha it's something to do with integer promotion rules.
>
>
> T

WAT! Thanks for posting this before it bit me!



April 30
On 4/30/24 20:19, Steven Schveighoffer wrote:
> ```d
> ubyte a;
> const(ubyte) b;
> 
> auto x = true ? a : b;
> 
> pragma(msg, typeof(x)); // int
> ```
> 
> Why? This isn't a VRP problem, as both are `ubyte`.
> 
> Related issue
> 
> https://issues.dlang.org/show_bug.cgi?id=19817
> 
> -Steve

FWIW, my frontend says `ubyte` here and there is a comment somewhere that claims it implements some rules from TDPL page 60.
May 01

On Tuesday, 30 April 2024 at 21:18:36 UTC, Timon Gehr wrote:

>

On 4/30/24 20:19, Steven Schveighoffer wrote:

>
ubyte a;
const(ubyte) b;

auto x = true ? a : b;

pragma(msg, typeof(x)); // int

Why? This isn't a VRP problem, as both are ubyte.

Related issue

https://issues.dlang.org/show_bug.cgi?id=19817

-Steve

FWIW, my frontend says ubyte here and there is a comment somewhere that claims it implements some rules from TDPL page 60.

Thanks to phone OCR, this is what is on that page:

1. If a and b have the same type, T is that type;
2. else if a and b are integrals, first promote anything smaller than 32-bit to int, then choose T as the larger type, with a preference for unsigned type if tied in size;
3. else if one is an integral and the other is a floating-point type, T is the floating-point type;
4. else if both have floating-point types, T is the larger of the two;
5. else if the types have a common supertype (e.g., base class), T is that supertype (we will return to this topic in Chapter 6);
6. else try implicitly converting a to b's type and b to a's type; if exactly one of these succeeds, T is the type of the successful conversion target;
7. else the expression is in error.

It seems rule 2 would apply instead of rule 6? but I don't like it.

-Steve

May 01
On 5/1/24 16:42, Steven Schveighoffer wrote:
> On Tuesday, 30 April 2024 at 21:18:36 UTC, Timon Gehr wrote:
>> On 4/30/24 20:19, Steven Schveighoffer wrote:
>>> ```d
>>> ubyte a;
>>> const(ubyte) b;
>>>
>>> auto x = true ? a : b;
>>>
>>> pragma(msg, typeof(x)); // int
>>> ```
>>>
>>> Why? This isn't a VRP problem, as both are `ubyte`.
>>>
>>> Related issue
>>>
>>> https://issues.dlang.org/show_bug.cgi?id=19817
>>>
>>> -Steve
>>
>> FWIW, my frontend says `ubyte` here and there is a comment somewhere that claims it implements some rules from TDPL page 60.
> 
> Thanks to phone OCR, this is what is on that page:
> 
> ```
> 1. If a and b have the same type, T is that type;
> 2. else if a and b are integrals, first promote anything smaller than 32-bit to int, then choose T as the larger type, with a preference for unsigned type if tied in size;
> 3. else if one is an integral and the other is a floating-point type, T is the floating-point type;
> 4. else if both have floating-point types, T is the larger of the two;
> 5. else if the types have a common supertype (e.g., base class), T is that supertype (we will return to this topic in Chapter 6);
> 6. else try implicitly converting a to b's type and b to a's type; if exactly one of these succeeds, T is the type of the successful conversion target;
> 7. else the expression is in error.
> ```
> ...

Thanks! Did not have the book at hand myself.

> It seems rule 2 would apply instead of rule 6?

Indeed, I think technically DMD conforms to those rules, but my frontend does not, on this example.

> but I don't like it.
> 
> -Steve

Same. (Not biased.)
May 02

On Wednesday, 1 May 2024 at 14:42:25 UTC, Steven Schveighoffer wrote:

>
1. If a and b have the same type, T is that type;
2. else if a and b are integrals, first promote anything smaller than 32-bit to int, then choose T as the larger type, with a preference for unsigned type if tied in size;
3. else if one is an integral and the other is a floating-point type, T is the floating-point type;
4. else if both have floating-point types, T is the larger of the two;
5. else if the types have a common supertype (e.g., base class), T is that supertype (we will return to this topic in Chapter 6);
6. else try implicitly converting a to b's type and b to a's type; if exactly one of these succeeds, T is the type of the successful conversion target;
7. else the expression is in error.

It seems rule 2 would apply instead of rule 6? but I don't like it.

-Steve

Yes, those rules are often cumbersome. The promotions should look more like:

    ubyte   >  ushort  >   uint   >   ulong
      v          v           v          v
byte > >  short > >   int   > >  long  >
                 v           v          v
               float   >  double  >   real

To find the common type, go to the crossing of the rightmost and the downmost of the types
and if there is no type at this point, go one further right or if that is not possible go one further down. This works for all numeric basic types.
E.g. common(byte, ubyte) = short,
common(float, uint) = double,
common(long, ulong) = real

If real is 80bit, it can represent all values of long and ulong, because that has 64bit mantissa plus a sign bit (and an exponent, which is not necessary for integer values).
If real is smaller, at least we tried our best but the low bits of the value may get lost.

The result of all operators should be the common type. Especially for unary operators the result should always be the same type as the operand.
Calculation can be done in the processor word-size, but without explicit cast the result should be truncated to the common type.

May 02

On Thursday, 2 May 2024 at 12:34:03 UTC, Dom DiSc wrote:

>

Yes, those rules are often cumbersome. The promotions should look more like:

    ubyte   >  ushort  >   uint   >   ulong
      v          v           v          v
byte > >  short > >   int   > >  long  >
                 v           v          v
               float   >  double  >   real

To find the common type, go to the crossing of the rightmost and the downmost of the types
and if there is no type at this point, go one further right or if that is not possible go one further down. This works for all numeric basic types.
E.g. common(byte, ubyte) = short,
common(float, uint) = double,
common(long, ulong) = real

But let's take a step back. As far as integrals, they are the same type, it's just that one is const and one is not.

There is no rule that says if the types are the same type except for type modifiers, what should happen. I think there should be.

The result is very unexpected.

-Steve

May 02

On Thursday, 2 May 2024 at 16:16:23 UTC, Steven Schveighoffer wrote:

>

On Thursday, 2 May 2024 at 12:34:03 UTC, Dom DiSc wrote:

>

[...]

But let's take a step back. As far as integrals, they are the same type, it's just that one is const and one is not.

There is no rule that says if the types are the same type except for type modifiers, what should happen. I think there should be.

The result is very unexpected.

-Steve

I'm for not having types promote at all. it's been an endless source of bugs for me. it messes with metaprogramming.

May 02

On Thursday, 2 May 2024 at 16:25:15 UTC, DrDread wrote:

>

I'm for not having types promote at all. it's been an endless source of bugs for me. it messes with metaprogramming.

PLs that dont promote have their own problems too. The most obvious is that overflowing is more easy. At least promotion mitigates that.

However I'm quite sure that D promotions rules were not seen as such. It's more C compatibility, walking on the C tracks, to speak metaphorically.

« First   ‹ Prev
1 2 3