phobos's circle CI runs a busted version of DMD
jmh530
john.michael.hall at gmail.com
Wed Jan 11 16:59:01 UTC 2023
On Wednesday, 11 January 2023 at 13:51:43 UTC, jmh530 wrote:
> On Wednesday, 11 January 2023 at 13:26:57 UTC, Dukc wrote:
>> On Wednesday, 11 January 2023 at 01:03:33 UTC, deadalnix wrote:
>>> Sample code:
>>> ```d
>>> ushort ee = 1028;
>>> ee <<= 5U;
>>> ee >>= 5U;
>>> writeln(ee);
>>> ```
>>>
>>> Regular compiler: https://godbolt.org/z/TcbjP76fW (prints
>>> 1028)
>>> Circle CI: 64516 .
>>>
>>> Someone, the compiler manages to do a signed arithmetic shift
>>> on an unsigned.
>>
>> [The spec
>> says](https://dlang.org/spec/expression.html#shift_expressions) that `>>` means *signed* shift right. `>>>` is for unsigned shifts. So pedantically speaking, 64516 is the correct result.
>>
>> It's another issue whether that's good design though. For one,
>> it breaks the rule "do what C does, or don't compile". It'd be
>> more reasonable if `>>` was type-dependant shift right (as in
>> C) IMO.
>
> Not really. If you just do `>>` (i.e. not `>>=`), then you get
> 1028.
>
> ```d
> import core.stdc.stdio: printf;
> void main() {
> ushort ee = 32896; //starting from the second shift
> ushort ee_result = ee >> 5u;
> printf("the value of ee_result is %d\n", ee_result); //the
> value of ee_result is 1028
> }
> ```
>
> The problem is the combination with assignment, which is what
> makes it seem like a bug. According to [1], "the right operand
> is implicitly converted to the type of the left operand, and
> assigned to it." So what should happen is that `5U` is
> implicitly converted to `5` and a signed conversion should
> happen. The result should be 1028. 64516 seems like a weird
> result.
>
> [1]
> https://dlang.org/spec/expression.html#simple_assignment_expressions
Upon further investigation, the problem goes away when you cast
`5u` to ushort (since `5u` is a uint and not a ushort).
```d
import core.stdc.stdio: printf;
void main() {
ushort ee = 32896; //starting from the second shift
ee >>= (cast(ushort) 5u);
printf("the value of ee is %d\n", ee); //the value of ee is
1028
}
```
Not quite sure why the problem is there for the uint and not the
ushort, but it could be related to the sequence of integer
promotion and the casting. What happens seems inconsistent with
the spec. One weird thing is that if you change the cast from
ushort to ulong, then we don't have the problem. It is only uint
where we get the weird result.
More information about the Digitalmars-d
mailing list