Length comparison

Don Clugston dac at nospam.com.au
Tue Dec 5 05:49:16 PST 2006


xs0 wrote:
> Bill Baxter wrote:
>> This bit me just now:
>>
>>     if (-1 < somearray.length) {
>>     }
>>
>> Ouch.  Took me a while to figure out that that bit of code was the 
>> problem.
>>
>> Is there some way to make these kind of bugs less likely or easier to 
>> find?
> 
> It should be made illegal :) In particular:
> - comparing a negative constant with an unsigned variable
> - comparing a too large constant with a signed variable (like 
> 3_000_000_000 and something of type int)
> - setting an unsigned var to a negative constant (uint a = -1)
> 
> 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 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.

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.



More information about the Digitalmars-d mailing list