Why is this not a warning?

Basile B via Digitalmars-d digitalmars-d at puremagic.com
Thu Mar 17 05:35:27 PDT 2016


On Thursday, 17 March 2016 at 09:59:41 UTC, Dominikus Dittes 
Scherkl wrote:
> Or you can use an improved opCmp implementation in the 
> compiler, that only add additional runtime cost, [...]

The compiler could statically fix two cases, ALWAYS without 
runtime cost. I think that FPC does this: operand widening by 
promoting the unsigned operand to a signed one of a wider type, 
POC with a template:

import std.traits;

bool safeIntegralCmp(string op, L, R)(auto ref L lhs, auto ref R 
rhs)
if (isIntegral!R && isIntegral!L)
{
     // safe
     static if (is(Unqual!L == Unqual!R))
     {
         mixin("return lhs" ~ op ~ "rhs;");
     }
     else
     {
         // promote unsigned to bigger signed
         static if (isSigned!L && R.sizeof < 8)
         {
             long widenedRhs = rhs;
             mixin("return lhs" ~ op ~ "widenedRhs;");
         }
         else static if (isSigned!R && L.sizeof < 8)
         {
             long widenedLhs = lhs;
             mixin("return widened" ~ op ~ "rhs;");
         }
         // not fixable by operand widening
         else
         {
             pragma(msg, "warning, comparing a" ~ L.stringof ~ " 
with a" ~ R.stringof
                 ~ " may result into wrong results");
             mixin("return lhs" ~ op ~ "rhs;");
         }
     }
}

unittest
{
     int a = -1; uint b;
     assert(a > b); // wrong result
     assert(safeIntegralCmp!">"(a,b) == false); // fixed by 
promotion

     long aa = -1; ulong bb;
     assert(aa > bb); // wrong result
     assert(safeIntegralCmp!">"(aa,bb) == true); // not staticaly 
fixable, warning
}

The case where an implicit widening is done a warning could also 
be emitted (operand bla bla widened).





More information about the Digitalmars-d mailing list