1

Confusion rose because of this post. The author updated his post, and the result became clear. Conclusion: Java evaluates expressions from left to right

Closed!

As evaluation of expression is done from right to left the following code should store 5 in j:

int i=2;
int j=++i+i++;
System.out.println(j);

But I get 6 as the output, which forces me to re-think the right to left evaluation idea. Kindly explain the theory here.

Community
  • 1
  • 1
CᴴᴀZ
  • 521
  • 7
  • 20
  • 17
    The theory is that anyone who writes an expression like that should be shot. The above evidence, however, suggests that theory and practice differ. – Hot Licks May 03 '13 at 16:02
  • @Hot Licks, we don't know that he won't be shot for it yet. – Sconibulus May 03 '13 at 16:03
  • My eyes! Ze googles, zey do nothing! – Mike G May 03 '13 at 16:04
  • 1
    While evaluation is in fact done left-to-right, your expression would also result in 6 when evaluated right-to-left! – ValarDohaeris May 03 '13 at 16:07
  • 11 duplicate answers so far – Steve Kuo May 03 '13 at 16:11
  • @ValarDohaeris: Do explain Sir, how its **6** when evaluated from _right to left_ Am using JDK 1.7 – CᴴᴀZ May 03 '13 at 16:15
  • 1
    Cf the answer of Tim Goodman. – ValarDohaeris May 03 '13 at 16:18
  • @HotLicks:I would love to point a Gun to such coder, but I can't do that to my Interviewer. Sorry. ;) – CᴴᴀZ May 03 '13 at 16:19
  • 1
    Actually writing code like this: very, very bad. Understanding the meaning of `++i`, `i++` and evaluation order well enough to be *able to* understand code like this: good. – Tim Goodman May 03 '13 at 16:28
  • @ValarDohaeris:Tim has explained the working of `i++ + ++i` and `++i+i++`. He has no where stated that the expr would result in _6_ if evaluated _R to L_ – CᴴᴀZ May 03 '13 at 16:38
  • @TimGoodman: Agreed Sir Tim, but someone needs to explain this stuff to the _brainless_ interviewers! But I guess they promote learning of every _basic_ aspect of a language, and am striving for it. :) – CᴴᴀZ May 03 '13 at 16:41
  • @ChaZ, you understand that you have to evaluate both `++i` and the `i++` before summing them, right? What @Valar is saying is that if you evaluate `i++` before `++i` it would change the value of those two expressions but the sum would still be the same (as illustrated in my answer where I actually rearranged the sum to force it to evaluate the terms in the opposite order. – Tim Goodman May 03 '13 at 16:41
  • Your "conclusion" seems a bit wrong, in other words. The sum you get would be the same in a language that evaluates the right term of the sum first. – Tim Goodman May 03 '13 at 16:42
  • I feel like you're trying to read it as `((++i)+i)++` but that's not really right, `i++` is still evaluated before summing, it just uses the value that it got *before* incrementing (as if it's stored in a temp variable, like in my answer). Applying ++ at the end of an expression like that wouldn't actually work. – Tim Goodman May 03 '13 at 16:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29386/discussion-between-chaz-and-tim-goodman) – CᴴᴀZ May 03 '13 at 16:56

8 Answers8

7

You get 6 because it's 3 + 3:

  • the first OP is ++i which increments first (to 3) then that value is used
  • next OP is +i which adds 3 again
  • last OP ++ doesn't take part in the addition, but it increments i after using it
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • I got the _right to left_ confusion from [here](http://stackoverflow.com/questions/16360084/unary-operations-fused-with-assignment?answertab=votes#tab-top) – CᴴᴀZ May 03 '13 at 16:10
7

Your assumption is false. Here's what the documentation says :

All binary operators except for the assignment operators are evaluated from left to right

So

++i+i++

is equivalent to

(++i)+(i++)

where ++i is evaluated first.

This gives

3+3

which is 6 (and i has value 4 after this).

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
3

The first ++ increments i. The + adds i to itself. i is 3.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
3
int i = 2;
int j = ++i + i++;

is the same as

int i = 2;

// This part is from ++i
i = i + 1;
int left = i; // 3

// This part is from i++
int right = i; // 3
i = i + 1;

int j = left + right; // 3 + 3 = 6

If instead you'd done:

int i = 2;
int j = i++ + ++i;

that would be equivalent to:

int i = 2;

// This part is from i++
int left = i; // 2
i = i + 1;

// This part is from ++i
i = i + 1;
int right = i; // 4


int j = left + right; // 2 + 4 = 6

So the sum is the same, but the terms being summed are different.

Tim Goodman
  • 23,308
  • 7
  • 64
  • 83
1

Where'd you get the idea that it is right-to-left? It is left-to-right.

What are the rules for evaluation order in Java?

Community
  • 1
  • 1
Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
1

This how it works, since unary operators have more precedance than binary:

int i=2;
int j =(++i)+(i++);
        ^^^   ^^^ 
         3  +(i++) //The value of i is now 3.
        ^^^   ^^^
         3  +  3   //The value of i is incremented after it is assigned.
Rahul Bobhate
  • 4,892
  • 3
  • 25
  • 48
1

In Java and C#, the evaluation of subexpressions will be done left to right:

int j=++i + i++;

contains the following two subexpressions ++i and i++. These subexpressions will be evaluated in this order so this will translate into:

int j= 3 + 3;

As in Java and C#, the ++i will be executed returning 3 but i will be changed to 3 before the second i++. The second will return the current value of i which is 3 now and after i++ the value of i will be 4.

In C++ this would be undefined.

And in real-world, you do not want to type this code (except for code golfing)

BlueTrin
  • 9,610
  • 12
  • 49
  • 78
  • ahhh... _left to right_ makes me feel soo good Sir Trin! As now am relaxed, and actually I got the _right to left_ confusion from [here](http://stackoverflow.com/questions/16360084/unary-operations-fused-with-assignment?answertab=votes#tab-top) – CᴴᴀZ May 03 '13 at 16:12
  • 1
    Sebastien posted this link which seems very good: http://stackoverflow.com/questions/6800590/what-are-the-rules-for-evaluation-order-in-java – BlueTrin May 03 '13 at 16:14
  • @ChaZ: left to right apply to subexpressions, if you were to write 2+4*2, 4*2 would be evaluated first, but if you write (a++) + (b++) * (c++), then (b++) would be evaluated, then (c++) then (b++) * (c++) ... etc – BlueTrin May 03 '13 at 16:23
  • 1
    BlueTrin:Yes, because of _left to right_ precedence of `*` operator. The first evaluation of _(b++)_ is self-explanatory. – CᴴᴀZ May 03 '13 at 16:48
1

When evaluating an expression such as a+b, before you can add 'b' to 'a', you need to know what 'a' is. In this case, a is ++i, which is 3, and b is i++ which is 3. Evaluating right-to-left gives 3 + 3 = 6

The other other Alan
  • 1,868
  • 12
  • 21