study: use checkedint as a drop-in replacement of native long

mw mingwu at gmail.com
Sat Aug 15 04:28:05 UTC 2020


(This is a follow-up from the other thread:  
https://forum.dlang.org/thread/rdrqedmbknwrppbfixll@forum.dlang.org)


I start this new thread to discuss and improve the usage of 
std.experimental.checkedint
  as a drop-in replacement of native long.

https://dlang.org/phobos/std_experimental_checkedint.html


`Checked` is a struct, try to use it as a `long` require some 
substantial change of existing code that previously use native 
long.

I list 8 things I've found below. Suggestions or PR welcome, e.g. 
even on how to improve the current implementation of `struct 
Checked`, or help from the compiler.

Thanks.


https://github.com/mingwugmail/dlang_tour/blob/master/divbug.d#L38
------------------------------------------------------------------------
alias Long = Checked!long;


void use_checked() {
   long la, lb, lc;  // native
   Long ca, cb, cc;  // checkedint

   // 0. as array literal
   long[] larr = [1, 2, 3];
//Long[] carr = [1, 2, 3];  // Error: cannot implicitly convert 
expression [1, 2, 3] of type int[] to Checked!(long, Abort)[]
   Long[] carr = [checked(1L), checked(2L), checked(3L)];  // more 
verbose

   // 1. checkedint cannot be chain assigned
   la = lb = lc = 0;
//ca = cb = cc = 0;  // Error: expression cc.opAssign(0) is void 
and has no value
   ca = 0;  // have to do separately
   cb = 0;
   cc = 0;

   // 2. have to use .get to call math func
   writeln(std.math.sgn(la));
   writeln(std.math.abs(la));
//writeln(std.math.sgn(ca));  // Error: template std.math.sgn 
cannot deduce function from argument types !()(Checked!(long, 
Abort)), candidates are:
//writeln(std.math.abs(ca));  // Error: template instance 
std.math.abs!(Checked!(long, Abort)) error instantiating
   writeln(std.math.sgn(ca.get));  // need .get
   writeln(std.math.abs(ca.get));  // need .get

   // 3. no opBinaryLeft
   lc = la * lb;
//cc = la * cb;  // Error: can only * a pointer, not a int
   cc = cb * la;  // have to switch order

   // 4. std.conv don't work
   double d = 0;
   lb = d.to!long;
//cb = d.to!Long;  // Error: template instance 
std.conv.to!(Checked!(long, Abort)).to!double error instantiating
   cb = lround(d);

   lb = "0".to!long;
//cb = "0".to!Long; // Error: template std.conv.toImpl cannot 
deduce function from argument types !(Checked!(long, 
Abort))(string), candidates are:
   cb = "0".to!long; // work around ok

   // 5. cannot assign to shared
   static struct S {
     shared long sl;
     shared Long sL;
   }
   S s;
   s.sl = la;
//s.sL = la;  // Error: template 
std.experimental.checkedint.Checked!(long, 
Abort).Checked.opAssign cannot deduce function from argument 
types !()(long) shared, candidates are:
   cast()s.sL = la;  // need the `cast`

   // 6. format %d won't work
   writefln("%04d", la);      // output: 0000
//writefln("%04d", ca);      // Expected '%s' format specifier 
for type 'Checked!(long, Abort)'
   writefln("%s",   ca);      // output: Checked!(long, Abort)(0), 
can this be just be 0?
   writefln("%04d", ca.get);  // output: 0000

   // 7. atomic won't work
   core.atomic.atomicOp!"+="(s.sl, lb);
//core.atomic.atomicOp!"+="(s.sL, cb);  // Error: template 
instance core.atomic.atomicOp!("+=", Checked!(long, Abort), 
Checked!(long, Abort)) error instantiating
//core.atomic.atomicFetchAdd(s.sL, cb);  // Error: template 
core.atomic.atomicFetchAdd cannot deduce function from argument 
types !()(shared(Checked!(long, Abort)), Checked!(long, Abort)), 
candidates are:
}
------------------------------------------------------------------------



More information about the Digitalmars-d mailing list