import std.stdio;
void main() {
long a = -5000;
size_t b = 2;
long c = a / b;
writeln(c);
}
$ dmd divbug.d
$ ./divbug
9223372036854773308
$ ldc2 divbug.d
$ ./divbug
9223372036854773308
x86_64 x86_64 x86_64 GNU/Linux
$ dmd --version
DMD64 D Compiler v2.092.0
$ ldc2 --version
LDC - the LLVM D compiler (1.21.0):
based on DMD v2.091.1 and LLVM 10.0.0
built with LDC - the LLVM D compiler (1.21.0)
Default target: x86_64-unknown-linux-gnu
Host CPU: bdver2
It can NOT silently do this, at least a warning.
BTW, on Windows, dmd correctly output -2500.
Comment #3 by mingwu — 2020-08-13T07:45:31Z
Just because C++ did it doesn't means it's correct.
And D supposed to be an improvement of C++.
Comment #4 by default_357-line — 2020-08-13T07:48:08Z
I'm completely on mw's side here, even understanding why D does this. Silently casting negative signed to unsigned violates the foundational principle that at least on built-in types, implicit conversions should never throw away data.
Though I think it should be a spec enhancement issue, to correct 6.8.1.4.4: "The signed type is converted to the unsigned type." https://dlang.org/spec/type.html#usual-arithmetic-conversions
Comment #5 by b2.temp — 2020-08-13T07:51:13Z
I agree too that this is a bug but I think it should be closed as WONTFIX, to keep a certain form of recognition.
Comment #6 by mingwu — 2020-08-13T07:53:05Z
OK, let me write this in this way to show it's impact:
==================================
import std.algorithm;
import std.stdio;
void main() {
long[] a = [-5000, 0];
long c = sum(a) / a.length;
writeln(c);
}
==================================
$ ./divbug
9223372036854773308
Comment #7 by kinke — 2020-08-13T08:12:24Z
(In reply to mw from comment #2)
> BTW, on Windows, dmd correctly output -2500.
Not on Windows, but for 32-bit targets, as an unsigned 32-bit int is converted to a signed 64-bit long in that case, according to spec 6.8.1.4.3.
Comment #8 by mingwu — 2020-08-13T08:26:25Z
$ /mnt/c/project/dmd2/windows/bin64/dmd.exe --version
DMD64 D Compiler v2.092.0-dirty
Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved written by Walter Bright
Comment #9 by b2.temp — 2020-08-13T09:05:18Z
Werll after the new facts about the behavior on i386 I retire what I said ealier. This should not be closed. Tagged it as "wrong code".
Comment #10 by kinke — 2020-08-13T19:12:03Z
Removing the wrong-code tag, as code adhering to the spec isn't wrong.
Comment #11 by kinke — 2020-08-13T19:17:01Z
FWIW, in C# this is an error:
long a = -5000;
ulong b = 2;
long c = a / b; // Operator '/' is ambiguous on operands of type 'long' and 'ulong'
Comment #12 by mingwu — 2020-08-13T19:57:53Z
for the additional reference, the forum discussion is here:
https://forum.dlang.org/thread/[email protected]
Now both Java and C# did it more correct than D.
"""
At least I want a warning message, even with a turn-on command-line switch is fine, I personally will turn it on all the time, silently performing this conversions is horrible.
In many area of the language design, we need to make a choice between: correctness v.s. raw performance.
But at least we also need *explicit* visible warning message after we've made that choice:
-- especially warnings about *correctness* when the choice was made favoring performance
-- if the choice was made favoring correctness, user will notice the performance when the program runs.
Personally, I will favor correctness over performance in my program design decisions: make it correct first, and faster later; you never know before-hand where your program's bottleneck is.
I'm sure you know the famous quote:
"Premature optimization is the root of all evil!"
"""
Comment #13 by robert.schadek — 2024-12-13T19:10:58Z