Fun with casts

Discussion in 'Java' started by Mike Schilling, Apr 7, 2010.

  1. Consider the following code, which does not compile. What do you think is
    wrong with it?

    public class Stuff
    {
    int i = (int)12;
    int j = (int)+12;
    int k = (int)(+12);
    Integer ii = (Integer)12;
    Integer ij = (Integer)+12;
    Integer ik = (Integer)(+12);
    }

    There is one illegal line:

    Integer ij = (Integer)+12; // illegal

    While 12 can be cast to Integer, +12 cannot (nor can -12). Why is this, you
    wonder?

    AFAICT, it stems from the ambiguity between casts and parenthesized
    expressions. Consider

    (1) long l = (long)+12;
    (2) long ll = (l)+12;

    The two are identical syntactically, but

    In 1, () indicates a cast and + is unary
    In 2, () parenthesizes an expression and + is binary

    Java parsers seem to disambiguate these using the rule that a possible cast
    preceding '+' or '-' should be parsed as a cast only if what's inside the
    parentheses is a built-in type. That's easy to apply since it doesn't
    require determining all of the types that are in scope at that point: the
    set of built-in types is fixed. You can see it being applied in errors
    produced by javac:

    boolean b = (boolean)+7;
    Object o = (Object)+7;

    inconvertible types
    found : int
    required: boolean
    boolean b = (boolean)+7;
    ^

    vs.

    cannot find symbol
    symbol : variable Object
    Object o = (Object)+7;

    Thus

    (Integer)+12

    is disallowed apparently because it would break thst rule.
     
    Mike Schilling, Apr 7, 2010
    #1
    1. Advertising

  2. On 04/07/2010 06:03 PM, Mike Schilling wrote:
    > Java parsers seem to disambiguate these using the rule that a possible cast
    > preceding '+' or '-' should be parsed as a cast only if what's inside the
    > parentheses is a built-in type. That's easy to apply since it doesn't
    > require determining all of the types that are in scope at that point: the
    > set of built-in types is fixed. You can see it being applied in errors
    > produced by javac:


    Or maybe it's because boolean is a keyword in the lexer, while Integer
    and Object et al. are identifiers.


    CastExpression:
    ( PrimitiveType ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus

    So if you have a + or - in your unary expression, the lexer forbids you
    from being able to cast it to make it unambiguous. Keep in mind that an
    Identifier is both a ReferenceType and an ExpressionName, so you could
    build either the parse tree [1]
    AdditiveExpression
    Primary IntegerLiteral
    ( ExpressionName ) +

    or
    CastExpression
    ( ReferenceType ) UnaryExpression
    + IntegerLiteral

    Having unambiguous grammars is a good thing. It makes things easier to
    parse.

    [1] I'm ignoring the multiple levels of single children here.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Apr 7, 2010
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Q2hyaXMgRGF2b2xp?=

    Web casts in ASP.Net

    =?Utf-8?B?Q2hyaXMgRGF2b2xp?=, Oct 19, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    512
    clintonG
    Oct 19, 2005
  2. cgbusch
    Replies:
    2
    Views:
    331
    Sudsy
    Jul 8, 2003
  3. Andy Fish
    Replies:
    65
    Views:
    1,765
    Mabden
    May 18, 2004
  4. dolphin
    Replies:
    4
    Views:
    323
    Jorgen Grahn
    Aug 25, 2007
  5. er
    Replies:
    2
    Views:
    509
Loading...

Share This Page