Walter Bright:

Here there are no new language features required. muls() being an intrinsic means the compiler knows about it. The compiler already does data flow analysis on constants, meaning it knows that x is 100,

Another example program, hopefully more clear:


void main(in string[] args) {
    import std.stdio, std.conv, std.experimental.safeintegral;

    assert(args.length == 3);
    immutable ubyte ux = args[1].to!ubyte;
    immutable ubyte uy = args[2].to!ubyte;
    SInt x = ux;
    SInt y = uy;

    immutable SInt result = x * y;
    assert(!result.overflow);
    writeln("Product: ", result);
}


Here SInt is a safe integral struct, that overloads the operators like "*" and internally calls muls().

In this program x and y are not constants (like in my original program, but here it's more visible).

What I'd like is the compiler to replace the call to muls() inside the opBinary() of SInt with a simple unsafe integer multiplication because the value range of x and y is [0, 255] for both, so the compiler knows the multiplication can't overflow.

How do you do this with no additional language features?

In my opinion the opBinary() of SInt needs a way to know at compile-time that the range of the two inputs are small enough to not overflow (so opBinary() becomes like a template with two instantiations).

Bye,
bearophile

Reply via email to