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.