Length comparison

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Tue Dec 5 07:02:04 PST 2006


Don Clugston wrote:
> xs0 wrote:
<snip>
>> For other cases, comparing signed with unsigned should produce a 
>> warning and, more importantly, work properly:
>>
>> int a;
>> uint b;
>>
>> a < b  should be  a < 0 || cast(uint)a < b
>> a > b  should be  a > 0 && cast(uint)a > b
>> etc.etc.
>>
>> I'm quite sure someone will say that's much slower so shouldn't be 
>> done, but:
>> - you can do it properly and only compare variables of the same type 
>> in the first place
>> - you can trivially make it fast again by casting, with the positive 
>> side effect of explicitly stating whether you want to use signed or 
>> unsigned comparison
> 
> But then you have to explicitly specify the type. In your code above, 
> suppose that later on, someone changes 'a' to 'long', and sets a = 
> (1L+int.max)*10 , b=7. Now, the code compiles, but it tells you that a < 
> b  !!!
> You've introduced a bug.

I think his point was that the compiler should perform this 
transformation automatically, i.e. compile "a < b" as if it said "(a < 0 
|| cast(uint)a < b)".
Extrapolating, if 'a' was changed to a long, the compiler should then 
compile it as if transformed as above, except with the cast changed to 
"cast(ulong)".
So yes, if done manually this introduces a bug, but if that just becomes 
the new meaning of comparing a signed and unsigned integer then it 
should work without a problem. I think this is a good idea.

>> - I doubt signed/unsigned comparisons are common enough to even make 
>> any noticeable speed difference
> 
> I think the underlying problem is, there's no way to specify a 
> 'positiveint' type, ie, a number in the range 0..int.max, which can 
> therefore be cast to both int and uint without error.

If opCast could be overloaded this might be possible with a struct, but 
it wouldn't be pretty (at least, not without also needing implicit casts 
and overloaded opAssign).
But AFAIK as it is, in the current language you're right that this can't 
be done.

> So you have to declare such variables as either 'int' (implying that 
> they can in theory be <0) or as 'uint' (implying that that they can in 
> theory be >int.max). Neither choice is good. There's no way to "do it 
> properly". It's a personal tradeoff which one you use.
> 
> And for this reason, comparing signed variables with unsigned variables 
> is almost never an error (when people use 'uint', they almost always 
> mean 'positive int'). Detecting mismatch comparisons with literals would 
> be a good thing, though.

Yes it would be a good thing if this was detected.
IMHO it would be an even better thing if the automatic transformation 
above would then be performed when such a mismatch is detected :).



More information about the Digitalmars-d mailing list