[Issue 259] Comparing signed to unsigned does not generate an error
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Fri Apr 17 01:49:01 PDT 2015
https://issues.dlang.org/show_bug.cgi?id=259
Dominikus Dittes Scherkl <dominikus at scherkl.de> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |dominikus at scherkl.de
--- Comment #58 from Dominikus Dittes Scherkl <dominikus at scherkl.de> ---
The problem is still there, and the behaviour is completely inconsistent, so
braking any code isn't a problem I think because I cannot imagine that anybody
really relies on the strange behaviour:
unittest
{
byte a = -3;
ubyte b = 2;
short c = -3;
ushort d = 2;
int e = -3;
uint f = 2;
long g = -3;
ulong h = 2;
assert(a < b);
assert(c < d);
assert(e < f); // fails!!
assert(g < h); // fails!!
assert(a < h); // fails!!
assert(b > g);
assert(d > e);
}
So why don't we change to something that simply always works?
int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow
if(is(Unqual!T == Unqual!U) || isFloatingPoint!T || isFloatingPoint!U)
{
// Should be buildin. Naive implementation:
return a <= b ? a != b ? -1 : 0 : 1;
}
/// Returns negative value if a < b, 0 if they are equal or positive value if a
> b.
/// This will always yield a correct result, no matter which integral types are
compared.
/// It uses one extra comparison operation if and only if
/// one type is signed and the other unsigned but has bigger max.
int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow
if(isIntegral!T && isIntegral!U && !is(Unqual!T == Unqual!U))
{
static if(T.sizeof == U.sizeof) alias C = Unsigned!T;
else alias C = CommonType!(T, U); // this will be the larger type
static if(isSigned!T && isUnsigned!U && T.sizeof <= U.sizeof)
{
return (a < 0) ? -1 : opCmp(cast(Unsigned!C)a, cast(C)b);
}
else static if(isUnsigned!T && isSigned!U && T.sizeof >= U.sizeof)
{
return (b < 0) ? 1 : opCmp(cast(C)a, cast(Unsigned!C)b);
}
else
{
// both signed or both unsigned or the unsigned type is smaller
// and can therefore be safely cast to the signed type
return opCmp(cast(C)a, cast(C)b);
}
}
--
More information about the Digitalmars-d-bugs
mailing list