Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2008

Tip: Looking for answers? Try searching our database.

Question on associativity and precedence

Thread view: 
ankur - 04 Jul 2008 20:30 GMT
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.
Eric Sosman - 04 Jul 2008 20:37 GMT
> int[] z = {10,20,30,40,50};
>         int index = 4;
[quoted text clipped - 23 lines]
> Why z[2] is not assigned 2?? How can this be explained in terms of
> associativity and precedence rules.

    Associativity and precedence cannot explain it.  Evaluation
order, though, can and does.

    Try printing the value of `index' before and after the
`z[index]=' line, and maybe things will start to make more sense.

Signature

Eric Sosman
esosman@ieee-dot-org.invalid

Mark Space - 04 Jul 2008 20:59 GMT
> 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.
Roedy Green - 04 Jul 2008 22:27 GMT
On Fri, 4 Jul 2008 12:30:22 -0700 (PDT), ankur
<ankur.a.agarwal@gmail.com> 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.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Joshua Cranmer - 04 Jul 2008 22:48 GMT
> On Fri, 4 Jul 2008 12:30:22 -0700 (PDT), ankur
> <ankur.a.agarwal@gmail.com> wrote, quoted or indirectly quoted someone
[quoted text clipped - 4 lines]
> 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?"

Signature

Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Lew - 04 Jul 2008 23:46 GMT
> Certainly, it's not at as stupid as the ageless C question "What does
> i=i++ evaluate to?"

And the answer to that old chestnut is: loss of one's job as a programmer.

Signature

Lew

Joshua Cranmer - 04 Jul 2008 22:40 GMT
> 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.

Signature

Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Mark Space - 05 Jul 2008 01:12 GMT
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:

> Generated bytecode (roughly):
>
[quoted text clipped - 6 lines]
> 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.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.