Is this reasonable?

eles eles at eles.com
Thu Dec 5 13:27:45 PST 2013


On Thursday, 5 December 2013 at 17:44:18 UTC, H. S. Teoh wrote:
> On Thu, Dec 05, 2013 at 06:15:37PM +0100, Steve Teale wrote:
>> Here I feel like a beginner, but it seems very unfriendly:
>> 
>> import std.stdio;
>> 
>> struct ABC
>> {
>>    double a;
>>    int b;
>>    bool c;
>> }
>> 
>> ABC[20] aabc;
>> 
>> void foo(int n)
>> {
>>    writefln("n: %d, aabc.length: %d", n, aabc.length);
>>    if (n < aabc.length)
>>       writeln("A");
>>    else
>>       writeln("B");
>> }
>> 
>> void main(string[] args)
>> {
>>    int n = -1;
>>    foo(n);
>> }
>> 
>> This comes back with "B".
>> 
>> If I change the test to (n < cast(int) aabc.length), then all 
>> is
>> well.
>> 
>> Is this unavoidable, or could the compiler safely make the
>> conversion implicitly?
>
> Comparing a signed value to an unsigned value is a risky 
> operation. You
> should always compare values of like signedness, otherwise 
> you'll run
> into problems like this.
>
> You can't compare -1 to an unsigned value because if that 
> unsigned value
> happens to be uint.max, then there is no machine instruction 
> that will
> give the correct result (the compiler would have to substitute 
> the code
> with something like:
>
> 	uint y;
> 	if (x < 0 || cast(uint)x < y) { ... }
>
> which will probably introduce undesirable overhead.
>
> The compiler also can't automatically convert aabc.length to 
> int,
> because if the length is greater than int.max (which is half of
> uint.max), the conversion would produce a wrong negative value 
> instead,
> and the comparison will fail.
>
> So, comparing a signed value to an unsigned value is a 
> dangerous,
> error-prone operation.  Sadly, dmd doesn't warn about such risky
> operations; it just silently casts the values. Bearophile has 
> often
> complained about this, and I'm starting to agree. This is one

me too, me too, me too


More information about the Digitalmars-d-learn mailing list