Re: Java puzzler
On Thu, 12 May 2011, Patricia Shanahan wrote:
On 5/12/2011 5:40 PM, markspace wrote:
On 5/12/2011 4:05 PM, Patricia Shanahan wrote:
If (byte)100 + (byte)100 caused an overflow, I would need an unsigned
byte type to do the same job.
OK, I think I understand. If the goal is to allow unsigned arithmetic
with automatic overflow detection, they we'd have to add unsigned
integer primitives to the language.
The original proposal was to make all arithmetic detect overflow, and
that would remove the existing ability to do unsigned arithmetic by
ignoring overflow.
The semantics of which, i've realised, is an utter can of worms. Does
this:
byte b = 100;
byte c = (b + b) - b;
Throw an exception? A interpreter which evaluates expression-by-expression
would blow up when it came to the b + b. An optimising compiler can pretty
easily optimise that expression out of existence altogether, but in doing
so, it eliminates any opportunity to detect an overflow. If you require
the exception, you close the door to a lot of optimisations.
One semantics that would work (i think) would be that all expressions are
evaluated at infinite precision, and overflow is checked for on assignment
to a variable (or parameter, etc). That might be rather hard to implement.
Also, it means that this:
byte b = 100;
byte c = b + b;
byte d = c - c;
// c is never used after this point
Would not mean the same thing as this:
byte b = 100;
byte d = (b + b) - (b + b);
Because one puts the intermediate value through a variable, and the other
does not. That's not great.
Would it be okay if i changed my mind again? :)
Seriously, having thought about it more, i think that:
byte b = 100;
int i = b + b;
assert i == -56;
Is absolutely fine. At the point at which you're adding b to itself,
you're adding bytes, so it's perfectly natural that they add using the
rules of bytes. It's only when you assign to the int variable that the
type changes to int. After all, if i wrote:
List l = Arrays.asList("int", "i", "=", "b", "+", "b");
Collection c = l.subList(0, 2);
The call to subList is allowed, because the expression l.subList(0, 2) is
evaluated according to the type l has where it's declared, not the type
it's about to be assigned to. Widening conversions of primitives and
pointers are very different things, but i don't think they should be
gratuitously different.
How about this:
short one = 1;
short two = 2;
float aHalf = one / two;
What should the value of aHalf be?
tom
--
The RAMAN VESSEL enters the SOLAR SYSTEM. The explorers explore it,
and it is COOL. Then they LEAVE. Then the Raman vessel LEAVES. --
Book-A-Minute SF/F