Treating the abusive unsigned syndrome
Michel Fortin
michel.fortin at michelf.com
Wed Nov 26 08:08:36 PST 2008
On 2008-11-26 10:24:17 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:
> Well that at best takes care of _some_ operations involving constants,
> but for example does not quite take care of array.length - 1.
How does it not solve the problem. array.length is of type uint, 1 is
polysemous(byte, ubyte, short, ushort, int, uint, long, ulong). Only
"uint - uint" is acceptable, and its result is "uint".
> Also consider:
>
> auto delta = a1.length - a2.length;
>
> What should the type of delta be? Well, it depends. In my scheme that
> wouldn't even compile, which I think is a good thing; you must decide
> whether prior information makes it an unsigned or a signed integral.
In my scheme it would give you a uint. You'd have to cast to get a
signed integer... I see how it's not ideal, but I can't imagine how it
could be coherent otherwise.
auto diff = cast(int)a1.length - cast(int)a2.length;
By casting explicitly, you indicate in the code that if a1.length or
a2.length contain numbers which are too big to be represented as int,
you'll get garbage. In this case, it'd be pretty surprising to get that
problem. In other cases it may not be so clear-cut.
Perhaps we could add a "sign" property to uint and an "unsign" property
to int that'd give you the signed or unsigned corresponding value and
which could do range checking at runtime (enabled by a compiler flag).
auto diff = a1.length.sign - a2.length.sign;
And for the general problem of "uint - uint" giving a result below
uint.min, as I said in my other post, that could be handled by a
runtime check (enabled by a compiler flag) just like array bound
checking.
One last thing. I think that in general it's a much better habit to
change the type to signed prior doing the substratction. It may be
harmless in the case of a substraction, but as you said when starting
the thread, it isn't for others (multiply, divide, modulo). I think the
scheme above promotes this good habit by making it easier to change the
type at the operands rather than at the result.
>> I'd make "auto x = 1" create a signed integer variable for the sake of
>> simplicity.
>
> That can be formalized by having polysemous types have a "lemma", a
> default type.
That's indeed what I'm suggesting.
>> And all this would also make "uint x = -1" illegal... but then you can
>> easily use "uint x = uint.max" if you want to enable all the bits. It's
>> easier as in C: you don't have to include the right header and remember
>> the name of a constant.
>
> Fine. With constants there is some mileage that can be squeezed. But
> let's keep in mind that that doesn't solve the larger issue.
Well, by making implicit convertions between uint and int illegal,
we're solving the larger issue. Just not in a seemless manner.
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list