is this intended behavior?

Don Clugston dac at nospam.com.au
Wed Apr 11 12:54:58 PDT 2007


James Dennett wrote:
> Don Clugston wrote:
>> Derek Parnell wrote:
>>> On Mon, 09 Apr 2007 15:01:56 -0400, Frank Malone wrote:
>>>
>>>> dmd v1.010
>>>>
>>>> import std.stdio;
>>>> void main() {
>>>>         uint a = 3;
>>>>         ubyte b = 3;
>>>>         int c = -1;
>>>>         writefln(c < a ? "true" : "false"); // outputs false
>>>>         writefln(c < b ? "true" : "false"); // outputs true
>>>> }
>>> Yes, kind of ... it is undefined behaviour ... the compiler doesn't know
>>> what to do so it does something dumb instead. I believe that a warning
>>> (a.k.a "error" in Walter-speak) should be issued by the compiler.
>> I agree.
>> I think we should seriously consider the possibility that literals
>> should be treated differently to variables, as regards signed-unsigned
>> mismatches.
>> * If the value fits in the range 0..int.max, it should be implicitly
>> convertible to int, or to uint. --> 100% guaranteed safe.
>> * If it is outside that range, an error should be issued, since it is
>> definitely a bug.
>>
>> My feeling is, that this would eliminate most of the annoying & useless
>> signed/unsigned mismatch warnings, and catch many of the real bugs.
> 
> It's a shame if a language can't make the code above
> do the right thing, and the right thing is simple:
> -1 is less than 3, report that.  Don't try to make
> comparisons convert their arguments to a common type.
> 
> With an int a and a uint b, "a<b" should give the
> same result as "(a<0) || ((uint)a < b)" -- where the
> conversion happens only in cases where it fits.  In
> general, if the value of one side of the comparison
> is out of range for the other side, the answer is
> known without testing the other value.  Concretely,
> for example, -3 < (uint)x for all x, and similarly
> 257 > (ubyte)y for all y.
I don't think that's necessarily true. -3 < (uint)x is quite likely to 
be a bug. I would want an error message if I ever wrote that -- it 
doesn't make sense. OTOH (uint)x > 3 makes perfect sense, as does (int)x>3.

The underlying problem is that uint doesn't necessarily mean "positive 
integer", it just means "no sign bit"; it could be the low part of a 
multi-byte integer, for example. Whereas a positive literal in the range 
0..int.max has no such ambiguity.



More information about the Digitalmars-d mailing list