A strange div bug on Linux x86_64, (both dmd & ldc2): long -5000 / size_t 2 = 9223372036854773308

jmh530 john.michael.hall at gmail.com
Thu Aug 13 23:33:25 UTC 2020

On Thursday, 13 August 2020 at 21:09:41 UTC, Guillaume Piolat 
> [snip]
> Feels correct to me !
> When you have an unsigned and signed integer mixed with a 
> binary operator, the operands are converted to unsigned.
> This is how it works in C and C++ and we wouldn't be able to 
> port C code to D if this were to be changed.

One way to look at it is that a design goal of D is that a C user 
should be able to copy and paste code into D with minimal 
changes. From that perspective, the integer promotion rules make 
sense. However, if the design goal were instead based upon 
automatic conversion of C code to D, particularly given the 
(mostly) automatic conversion of dmd from C to D, then different 
integer promotion rules would not have been as significant a 
blocker for people coming to D from C. At this point, it would be 
a big breaking change.

Also, we have templates and operator overloading. Nothing stops 
people from making their own Int type that has different 
semantics for division.

import std.traits: isIntegral;

struct Integer(T)
     if (isIntegral!T)
     T x;
     alias x this;

     Integer!T opBinary(string op)(size_t rhs)
         assert(rhs < int.max);
         static if (op == "/")
             return Integer!T(x / cast(T) rhs);
             static assert(0, "Operator " ~ op ~ " not 

void main() {
     auto x = Integer!long(-5000L);
     size_t y = 2;
     auto z = x / y;
     import std.stdio: writeln;
     assert(z == -2500);

More information about the Digitalmars-d mailing list