On Monday, 22 January 2024 at 01:14:06 UTC, Steven Schveighoffer wrote:
On Sunday, 21 January 2024 at 16:05:40 UTC, Gavin Gray wrote:
The following code:

  ulong charlie = 11;
  long johnstone = std.algorithm.comparison.max(0, -charlie);
  writeln(format!"johnstone %s"(johnstone));

Results in (without any warning(s)):
johnstone -11

However you choose to look at it, this means -11 > 0 (regardless of all arguments concerning implicit conversions, 1's and 2's complements, being efficient, etc).

The language should not allow unary unsigned anything.

This is unlikely to get fixed, just due to the nature of D's philosophy when it comes to C compatibility.

It would also break a lot of existing code.

-Steve

Well there was no problem breaking my code for this (which you even proposed should be fixed):

```
foreach(int i, v; arr) {
  // i is not an int until you do i.to!int
}
```

The compiler knows it's converting from a ulong to a long:

```
ulong a = -11;
writeln(a);
// 18446744073709551605
long b = a;
writeln(b);
// -11
```

It's impossible for both to be the intended behavior. Anyone doing that on purpose (which I suspect is extremely rare) would be doing it because they want b equal to 18446744073709551605. I don't see why this should be treated the same as an int to long conversion because it very much changes the value.

There needs to be a safe arithmetic mode because the current behavior of `double j = 10 / 3;` is not what anyone expects and is a bug 100% of the time. I've said multiple times that it's silly to spend so much time on memory safety if the language is going to allow stuff like this without a simple way to prevent it.

Reply via email to