Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Array

 
Netty poestel
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


how shall one interpret this line -->( a [ (a = b)[3] ] ); ?


( tags added)
[ December 01, 2004: Message edited by: Barry Gaunt ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Like:
 
Netty poestel
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
funny, now it seems all so easy
 
Jugal Hans
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Orginal code pasted below:


It is still hard to evaluate
I know finaly value in a[0] is displayed bcoz i ran the code to see.
But I dont understand how did that happen ??
This is what i thought:
After a = b array a will also display the same values as array b
which means
a[0] = 2
a[1] = 3
a[2] = 1
a[3] = 0
so a [ (a = b)[3] ] will evaluate to a[0] which is 2, but why does it display the old array element ???
Please help me understand this !!!

Thanks
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This one is all about operand evaluation. You start with this (I included a picture of the arrays because it helps be keep track of what references what):



We start evaluating operands from left to right. Therefore, we first evaluate the 'a' on the far left. That's a simple evaluation and comes out to be the array {1, 2, 3, 4}.

That leaves us with an expression that looks something like this (imagine this was real code):



Before anything else can be evaluated, we need to first take care of the assignment, a = b. When we do that, we assign the reference to our "b" array to our variable "a". Now, both array references, a and b, reference the same array, the one originally referenced by b. In addition, an assignment operation returns a reference (or the value) that was just assigned. So, we get back a reference to our array and we're left with essentially this:



Now, we need to evaluate a[3] before we can evaluate "{1, 2, 3, 4}[ a[3] ]". As our variable 'a' now references the array originally referenced by b, a[3] evaluates to 0. That leaves us with this:



Simply, that evaluates to 1.

Edited By Corey McGlone: I fixed this post because I was stupid and wrong. I believe it is correct now.
[ December 01, 2004: Message edited by: Corey McGlone ]
 
Jugal Hans
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the explaination.
So you also agree to the fact that it should display 2,
but on compiling and running the above code it displays 1
why ???
[ December 01, 2004: Message edited by: Jugal Hans ]
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jugal Hans:
So you also agree to the fact that it should display 2,
but on compiling and running the above code it displays 1
why ???


Bah. Sorry about that. I need to test things before I type them. Once I was called on this, I quickly realized my mistake.

The problem with my response is that the operands are evaluated from left to right. That means that, with this expression:



The first 'a' (the one on the far left) is evaluated prior to anything else. It is even evaluated prior to the assignment of "a = b" so, when that 'a' is evaluated, it still references the array {1, 2, 3, 4}.

So, if you follow my logic through, you'll see that, in the end, you're going to evaluate a[0], which is, in fact, 1, not 2.

Sorry about that. I've changed my original post - hopefully no one else will be confused.
[ December 01, 2004: Message edited by: Corey McGlone ]
 
Jugal Hans
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guess I am back to "square 1"

OK,so does that mean at some point the array a was referencing two array values at the same time ???
1. when a=b[3] is evaluated
2. when the left most array a evaluated.

 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Ernest Friedman-Hill pointed out to me, this example comes straight from the JLS, here.

The JLS reads:


In an array access, the expression to the left of the brackets appears to be fully evaluated before any part of the expression within the brackets is evaluated. For example, in the (admittedly monstrous) expression a[(a=b)[3]], the expression a is fully evaluated before the expression (a=b)[3]; this means that the original value of a is fetched and remembered while the expression (a=b)[3] is evaluated. This array referenced by the original value of a is then subscripted by a value that is element 3 of another array (possibly the same array) that was referenced by b and is now also referenced by a.


In even more technical terms, think of it this way. The operand 'a' is first evaluated. The result of that is pushed onto the operand stack. Next, the operand (a=b)[3] is evaluated. Again, the result is pushed onto the operand stack. Finally, we need to evaluate our array index - to do that, we pop our array, as well as our index, from the stack and put them together.

Note that the array is pushed onto the stack prior to the reassignment of 'a'. So, in the end, 'a' doesn't point at 2 things at the same time - it can only reference one thing at a time. However, the operand stack can "remember" what 'a' originally referenced, so to speak.

Basically, the JVM figure out what array 'a' references and holds on to that array while the expression (a=b)[3] is evaluated. When that is done being evaluated, the number that results can be used to index the array that had been set aside for safe-keeping.

Make sense? I realize this is a confusion topic (and I'm probably not explaining it well) so, if you're still confused, let me know.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because it's so complicated is the reason (see my post above) for my simplistic code rewrite introducing the array reference variable a1. The compiler does not actually do that of course.

You can see what happens if you decompile the class with javap -verbose.
 
abhinav singhal
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please let me know whether the declaration of arrays is correct or not.
I think this declaration is not that of annonymous arrays.
its
int []a={1,2,3,4};which is incorrect

regards,
Abhi
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by abhinav singhal:
int []a={1,2,3,4};


Compile that and then tell me if you think it's incorrect or not.
 
prajkta patil
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks corey,
u have given very nice explanation.
i have one question:


why above code gives error if i didn't write System.out.println?
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because it is not a statement. Assign it to an int variable to get it to compile.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It also is possible to explain these interesting results without considering array evaluation as a special case in expression evaluation.

The postfix operator [] is at top of the operator precedence table. C++ programmers familiar with overriding operators will see [] as a binary operator. Because [] has the highest precedence, the left operand, a, is evaluated and a reference to object { 1, 2, 3, 4 } is pushed on the stack. The righthand operand, which changes a, results in 0 being pushed on the stack, then the [] operator yields a 1.

{ 1, 2, 3, 4 } operator[] 0 = 1
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic