views:

343

answers:

2

A simple expression like

(x) - y

is interpreted differently depending on whether x is a type name or not. If x is not a type name, (x) - y just subtracts y from x. But if x is a type name, (x) - y computes the negative of y and casts the resulting value to type x.

In a typical C or C++ compiler, the question of whether x is a type or not is answerable because the parser communicates such information to the lexer as soon as it processes a typedef or struct declaration. (I think that such required violation of levels was the nastiest part of the design of C.)

But in Java, x may not be defined until later in the source code. How does a Java compiler disambiguate such an expression?

It's clear that a Java compiler needs multiple passes, since Java doesn't require declaration-before-use. But that seems to imply that the first pass has to do a very sloppy job on parsing expressions, and then in a later pass do another, more accurate, parse of expressions. That seems wasteful.

Is there a better way?

+3  A: 

I just tested it out, and this code:

Double y = new Double(0.1);
System.out.println((Double)-y);

gives a compile error:

operator - cannot be applied to Double, java.lang.Double.

Putting parentheses around the -y makes it compile fine. So apparently Java solves this problem by simply not allowing it in the grammar (if that's the right terminology; I'm not an expert on compilers).

Michael Myers
Am I wrong, or did I not answer the question?
Michael Myers
I did not downvote, but if instead of Double you had used double the compiler would have allowed it, since _operator -_ can be applied to doubles. I believe that it was downvoted for that imprecission.
David Rodríguez - dribeas
Since Java 1.5, you can use any arithmetic operator with Doubles, Floats, etc. (because of autoboxing). As I said, adding parentheses made it compile without errors.
Michael Myers
+1 because I don't see any reason this answer should be voted into the negatives
dancavallaro
+4  A: 

I think I've found the solution that satisfies me. Thanks to mmyers, I realized that I needed to check the formal spec of the syntax for type casts.

The ambiguity is caused by + and - being both unary and binary operators. Java solves the problem by this grammar:

CastExpression:
        ( PrimitiveType Dimsopt ) UnaryExpression
        ( ReferenceType ) UnaryExpressionNotPlusMinus

(see http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#238146)

So, '+' and '-' are explicitly disallowed immediately after the ')' of a cast unless the cast uses a primitive type -- which are known by the compiler a priori.

Thom Boyer
I was too lazy to actually look up the spec (and I didn't know where to look anyway). +1
Michael Myers