22

In this code:

int y = 10; int z = (++y * (y++ + 5)); 

What I expected

First y++ + 5 will be executed because of the precedence of the innermost parentheses. So value of y will be 11 and the value of this expression will be 15. Then ++y * () will be executed. So 12 * 15 = 180. So z=180

What I got

z=176

This means that the VM is going from left to right not following operator precedence. So is my understanding of operator precedence wrong?

11
  • 31
    Precedence does NOT mean the order things are executed. Commented Mar 20, 2015 at 8:48
  • 11
    @Caramiriel I'm 99% sure this is not production code - this is just prodding and poking at the language & compiler, and the OP feels that they have found something unexpected. Commented Mar 20, 2015 at 11:13
  • 6
    @Loko Basic math doesn't have constructs like y++, since basic math doesn't have mutable variables (as far as I know). Commented Mar 20, 2015 at 13:47
  • 3
    Your understanding of operator precedence is wrong; this is a very common misunderstanding and many beginner books explain this completely wrong. These articles are about C# but the principles apply equally well to Java; they might help you. ericlippert.com/tag/precedence Commented Mar 20, 2015 at 15:20
  • 15
    The key thing to understand is that precedence determines the order in which the operators are executed, not the order in which the operands are executed. A() + B() * C() guarantees that the multiplication operation happens before the addition. The invocation of A() is neither a multiplication nor an addition, so precedence says nothing whatsoever about whether A() happens before B() and C(). Commented Mar 20, 2015 at 15:23

5 Answers 5

24

The expression (++y * (y++ + 5)); will be placed in a stack something like this:

1. [++y] 2. [operation: *] 3. [y++ + 5] // grouped because of the parenthesis 

And it will be executed in that order, as result

1. 10+1 = [11] // y incremented 2. [operation: *] 3. 11+5 = [16] // y will only increment after this operation 

The the expression is evaluated as

11 * 16 = 176 
Sign up to request clarification or add additional context in comments.

4 Comments

If you are working on a stack, the [operation: *] should come after the two inputs. It doesn't affect the important bits of what you're saying here, so it's just a minor quibble.
I find this answer quite confusing. If you're considering a stack machine, the operations are: compute the side effect and value of ++y and push the result on the stack, then compute the side effect and value of y++ and put the result on the stack, then push 5 on the stack, then pop two things off the stack, add them, and push the sum on the stack, then pop two things off the stack, multiply them, and put the product on the stack.
Okay, using post-fix notation it is expressed as [++y][y++][5]+* or 11 11 5 + *. During he first phase parsing it will push the 3 values into the stack [5][11][11] in that order. Next it will find the + operator and it will pop 2 values from the stack 11 and 5, the result of the operation, which is 16, will be pushed back into the stack, hence the stack state will be [16][11]. The next token is another operator *, so it will pop 2 values from the stack again and perform the operation: 11 * 16 (note: the 2nd value popped will be the first operand).
@OwenBringino Realistically a high level programming language will not use a "stack", it will implement the rules of the grammar. So your analogy falls apart easily.
14

First y++ + 5 will be executed because of the precedence of the innermost parentheses

Precedence and evaluation order are not the same thing. All binary expressions except the assignment expression are evaluated left-to-right. Therefore y++ is evaluated before the parenthesized expression on the right.

5 Comments

But then I don't understand the point of using parentheses in mathematical expressions
@EdmDroid Without any parenthesis, ++y * y++ + 5 would be evaluated just as (++y * y++) + 5 - that's a very different expression.
I guess the choice of the term "precedence" causes confusion. It's actually binding priority, regulating how a chain of binary operations parses syntactically, and not a temporal precedence.
While OP is confused, so is the answer: "All binary expressions except the assignment expression are evaluated left-to-right" is not correct or at least confusing: the multiplication is performed after the addition although the latter is to the right of the multiplication. What is true that among pairs of non-overlapping formulas, the leftmost one is evaluated before the rightmost one; concretely this applies to ++y on the left and y++ or its containing y++ + 5 on the right. On the other hand the formulas with * respectively + as operator overlap (latter is operand of former).
The latter is not to the right of multiplication, it is the right side of the binary multiplication expression. The rule is very simple: evaluate the left operand, then evaluate the right operand, then evaluate the binary expression itself. No overlaps need to be considered, the expressions are strictly nested into a tree structure.
13

The parentheses just describe how the sub-expressions will be grouped together. Parenthesizing doesn't mean it will be evaluated first. Rather, the rule in java is evaluate each sub-expression strictly from left to right.

Always remember that the order of evaluation has absolutely nothing to do with operator precedence and associativity.

Java Oracle documentation says that:

15.7. Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

Therefore, the expression (++y * (y++ + 5)) will be evaluated as

temp1 = ++y = 11 temp2 = y++ + 5 = 11 + 5 = 16 z = temp1*temp2 = 11*16 = 176 

Further reading: Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses but equally valid for too.

1 Comment

4
  1. First will be executed ++y. y will be 11.
  2. Then will be executed y + 5 (actually y++ + 5 can be written as 5 + y++ which is interpreted as (5 + y) and then y++). z will become 11 * 16 = 176.
  3. y will be 12 after the calculation finishes.

5 Comments

postfix ++ has higer precedence than binary +. It just happens that the value of the expression y++ is the value of y before the increment, but y is incremented as a side effect.
Why 5 + y++ will be interpreted as (5 + y)++ ?
I meant (5 + y) and then y++
Still wrong. It is not necessary that side effect to y will take place after y + 5.
Indeed, this answer is misleading. Though in this case you cannot tell whether the increment side effect happens before or after the addition, you can come up with an example where you can tell the difference. Java does not allow the side effect of the increment to be delayed until after the addition. (Imagine a world for instance where addition could throw an exception on overflow; the side effect of the increment must be observed before the exception is possibly thrown, because a catch could observe the incremented variable.)
1

The calculation is going on following order

 z= (++10 * (10++ + 5)) z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or * z= (11 * 16) z= 176 

4 Comments

Four upvotes to a wrong answer !! o.O
@haccks well to be fair, you haven't done anything to help people understand why it's wrong...
@DavidZ; Do you agree with the statement: Here right part will be evaluated first because of ()?
Precedence has nothing to do with order of evaluation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.