Length comparison

Don Clugston dac at nospam.com.au
Tue Dec 5 07:53:48 PST 2006


Frits van Bommel wrote:
> 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 :).

But if a mismatch was detected, would there be any way to request a fast 
comparison without introducing bugs?



More information about the Digitalmars-d mailing list