checkedint call removal

bearophile via Digitalmars-d digitalmars-d at puremagic.com
Sun Jul 27 06:52:09 PDT 2014


The core.checkedint module isn't meant to be used directly like 
this, it has the bricks to build partially library-defined safe 
integral types:


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

     assert(args.length == 3);
     immutable xy = args[1 .. $].to!(int[2]);

     bool overflow = false;
     immutable result = muls(xy[0], xy[1], overflow);
     assert(!overflow);
     writeln("Product: ", result);
}


Calls to core.checkedint functions are eventually meant to be 
replaced by faster compiler intrisics in all D compiler, that use 
the carry and overflow bits present in most CPUs.

But to be more useful, the compiler should replace safe integral 
operations with regular (faster) integral operations where it 
statically knows they can't overflow/underflow. In D there is 
value range propagation (that probably will be improved in 
future) that can be used for this. If the compiler replaces the 
calls to core.checkedint functions with intrinsics, it can also 
replace some calls with regular operations where it sees the 
value range makes an overflow impossible. This is a naive example:


void main() {
     import std.stdio, core.checkedint;
	
	ubyte x = 100;
	ubyte y = 200;	

     bool overflow = false;
     immutable result = muls(x, y, overflow);
     assert(!overflow);
     writeln("Product: ", result);
}


With a library-defined type the first program could look:


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

     assert(args.length == 3);
     SInt x = args[1].to!int;
     SInt y = args[2].to!int;

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


where the operator "*" of SInt calls muls().


But while operations with ubyte and int values are able to use 
the range of values (to avoid casts), a library-defined type like 
SInt that calls muls() currently loses the knowledge of the range 
of the operands. How do you solve this problem? If you solve this 
problem for SInt, you can solve it for lot of other 
library-defined types.

A possible piece of the solution is the recently suggested 
__trait(valueRange, exp), but alone that's not enough.

Bye,
bearophile


More information about the Digitalmars-d mailing list