Question on associativity and precedence

Discussion in 'Java' started by ankur, Jul 4, 2008.

  1. ankur

    ankur Guest

    int[] z = {10,20,30,40,50};
    int index = 4;
    z[index] = index = 2;

    System.out.println(z[0]);
    System.out.println(z[1]);
    System.out.println(z[2]);
    System.out.println(z[3]);
    System.out.println(z[4]);



    This code gives

    10
    20
    30
    40
    2

    Why does it not give:
    10
    20
    2
    40
    50

    Why z[2] is not assigned 2?? How can this be explained in terms of
    associativity and precedence rules.
    ankur, Jul 4, 2008
    #1
    1. Advertising

  2. ankur

    Mark Space Guest

    ankur wrote:

    > Why z[2] is not assigned 2?? How can this be explained in terms of
    > associativity and precedence rules.


    Good question. I think this is the answer:

    <http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.1>

    "If the left-hand operand is an array access expression ... then:

    * First, the array reference subexpression of the left-hand operand
    array access expression is evaluated.... "


    So that's the order because the JLS says it is.

    For assignment, a = (b = c); if "a" is an expression (?, I think
    "expression" is correct, the same section talks about fields too) a is
    evaluated first. Then "(b = c)" is evaluated. I'd assume that if "b"
    is an expression, it will be evaluated before "c". I'd have to look-up
    which one of those is precedence, and which is associativity. It may be
    both one or the other, too, I suppose.

    Finally, the assignments occur.
    Mark Space, Jul 4, 2008
    #2
    1. Advertising

  3. ankur

    Roedy Green Guest

    On Fri, 4 Jul 2008 12:30:22 -0700 (PDT), ankur
    <> wrote, quoted or indirectly quoted someone
    who said :

    >z[index] = index = 2;


    first of all, don't use cascaded assignment operators. The only time
    you see them in on exams.

    see http://mindprod.com/jgloss/precedence.html

    You will learn that = in evaluated right to left.

    Java has a horrible hodgepodge precedence and left to right and right
    to left operators mainly inherited from C.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Jul 4, 2008
    #3
  4. ankur wrote:
    > int[] z = {10,20,30,40,50};
    > int index = 4;
    > z[index] = index = 2;


    Generated bytecode (roughly):

    iconst_4 push 4 on to the stack
    istore <index> store the top of the stack (4) into index
    aload <z> load z to the stack
    iload <index> load index (4) on the stack
    iconst_2 push 2 on to the stack
    dup duplicate the top element (2) on the stack
    istore <index> store the top of the stack (2) into index
    iastore store the top of the stack into the index denoted by the
    second value on the stack of the array denoted by the
    third item of the stack.

    In general, an operand is resolved before any of the operands to the
    right of it and after any operand to its left, such that an assignment
    to its right does not affect any usages of the variable to its left.
    Left and right are defined, of course, in terms of the JLS and are more
    properly before and after, but human notation makes left/right clearer.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Jul 4, 2008
    #4
  5. Roedy Green wrote:
    > On Fri, 4 Jul 2008 12:30:22 -0700 (PDT), ankur
    > <> wrote, quoted or indirectly quoted someone
    > who said :
    >
    >> z[index] = index = 2;

    >
    > first of all, don't use cascaded assignment operators. The only time
    > you see them in on exams.


    Not quite true: I occasionally use something in the form of "x = y = 0"
    myself, but it tends to be rare.

    Certainly, it's not at as stupid as the ageless C question "What does
    i=i++ evaluate to?"

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Jul 4, 2008
    #5
  6. ankur

    Mark Space Guest

    >

    Reading the JLS a bit more, I found this:

    <http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.1>

    "Otherwise, three steps are required:

    * First, the left-hand operand is evaluated to produce a variable.
    If this evaluation completes abruptly, then the assignment expression
    completes abruptly for the same reason; the right-hand operand is not
    evaluated and no assignment occurs.
    * Otherwise, the right-hand operand is evaluated. If this
    evaluation completes abruptly, then the assignment expression completes
    abruptly for the same reason and no assignment occurs. "

    "Otherwise" means if the left hand operand of an assignment is neither a
    field or an array.

    But the point is the operand is evaluated "first to produce a variable."
    This is implies to me that there are two passes over a Java
    expression. First, to produce variables. This pass seems to go left to
    right. (I can't think of a case where grouping or precedence would make
    it go differently.)

    Then in the second pass the variables are evaluated with the specified
    order of operations. All expressions are evaluated here.

    The exception in both cases seems to be the short circuit operators,
    which may not evaluate their right hand variables or operations at all,
    depending on the value of the left hand expression.

    To me, that latter bit implies that expressions involving || and &&
    might evaluate differently than the OP's example.


    Getting back on track a bit:

    Joshua Cranmer wrote:

    > Generated bytecode (roughly):
    >
    > iconst_4 push 4 on to the stack
    > istore <index> store the top of the stack (4) into index
    > aload <z> load z to the stack
    > iload <index> load index (4) on the stack
    > iconst_2 push 2 on to the stack
    > dup duplicate the top element (2) on the stack
    > istore <index> store the top of the stack (2) into index
    > iastore store the top of the stack into the index denoted by


    I think the compiler could choose to evaluate "aload <z>" in a different
    order of the JLS were different. Get rid of the iconst_4 and move the
    evaluation of aload <z> down a bit and you get the effect the OP seems
    to be expecting. It's even one less byte code, I think. The compiler
    is doing extra work to conform to the JLS.
    Mark Space, Jul 5, 2008
    #6
    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. maadhuu
    Replies:
    3
    Views:
    345
    maadhuu
    Jul 29, 2005
  2. associativity and precedence

    , Oct 13, 2006, in forum: C Programming
    Replies:
    5
    Views:
    466
  3. vjay
    Replies:
    7
    Views:
    367
    Robin Kåveland Hansen
    Nov 27, 2007
  4. gwowen
    Replies:
    3
    Views:
    300
  5. Replies:
    6
    Views:
    941
    Nick Keighley
    Feb 18, 2010
Loading...

Share This Page