Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Side Effect Operator Java  RSS feed

 
Luca Olivieri
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello guys,

i'm new in javaRanch. I'm studying the operator ++/-- and doing some test try this:



I thought the result would have been :
first expression: 22 because first 11 (1+i) and then sum of 11 (++i)
while the second expression: 23 because first 11(++j) and then sum 1 + 11 (1 + j)

the result is the same for both the expression: 22

Why? Does the operator ++ has higher precedence in the absence of ()? Is There some sort of side effect? If yes, what's the side effect for a operator?

Thank you and sorry for my bad English
 
Henry Wong
author
Sheriff
Posts: 23283
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Luca Olivieri wrote:
I thought the result would have been :
first expression: 22 because first 11 (1+i) and then sum of 11 (++i)
while the second expression: 23 because first 11(++j) and then sum 1 + 11 (1 + j)

the result is the same for both the expression: 22

Why? Does the operator ++ has higher precedence in the absence of ()? Is There some sort of side effect? If yes, what's the side effect for a operator?


First, welcome to the ranch.

The evaluation order of expressions is specified by section 15.7 of the Java Language specification...

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7

And it's pretty simple. It is evaluated from left to right. Notice that there isn't any mention of precedence or parenthesis. As for when the side effect takes place, it happens as soon as the operator is evaluated (as soon as possible following the evaluation order).

Henry
 
Steffe Wilson
Ranch Hand
Posts: 165
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Luca Olivieri wrote:
System.out.println((1 + i) + ++i);
System.out.println(1 + j + ++j);

Hi,
As Henry says, but just to add clarification on something that I was checking up recently:

The prefix operators, eg ++x or --x, are actioned immediately before the value they refer to is used.

So in your second example the order of evaluation is...
1 plus j is 11,
then add ++j means j is incremented before being used, thus its value is 11,
so when it is added to the first 11 we get 22.

You could try this to see if it matches your expectations based on the above:

 
Luca Olivieri
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steef, Henry
thank you very much.
Your explanations were very helpful.

I think i know.

I think the compiler builds a tree expression and solves the expression in order visiting the tree.

 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16026
87
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Luca Olivieri wrote:I think the compiler builds a tree expression and solves the expression in order visiting the tree.

Yes, but to understand how an expression is evaluated, you don't really have to think about this.

The important thing to remember is the rule that Henry mentioned: Expressions are evaluated from left to right.

So, to see how an expression is evaluated, you just have to read it from left to right and fill in each part of the expression.

Ofcourse you'll also have to keep the precedence of operators in mind; in other words: an expression such as 2 + 3 * 4 means 2 + (3 * 4) = 14 and not (2 + 3) * 4 = 20.
 
Campbell Ritchie
Marshal
Posts: 55681
161
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesper de Jong wrote:. . . an expression such as 2 + 3 * 4 means 2 + (3 * 4) = 14 and not (2 + 3) * 4 = 20.
But it is not evaluated like this:-
  • 1: The * has a higher precedence so work out 3*4. That's 12.
  • 2: Add 2. That makes 14.
  • No, because that is not (as Jesper said) left‑to‑right. It is evaluated like this:-
  • 1: Start with 2.
  • 2: That has a + to its right, so add something.
  • 3: That something has a * in which has a higher precedence, so calculate that as 12
  • 4: Add 12: that makes 14.
  • You might get the same answer but that is only by luck. The second time round I did evaluate the arithmetic left‑to‑right.

    In Java Puzzlers by Bloch and Gafter, they ask what this expression does:-
    i ^= j ^= i ^= j;   (or similar).
    Now that is repeated bitwise exclusive‑OR‑ing the two numbers. So I got myself some paper and worked out that it would swap the values of the two ints (it cannot work for floating‑point numbers.) And I wrote myself the following little programAnd this is its output. It works beautifully, because C does not have a left‑to‑right rule.
    campbell@campbellsComputer:~/CPrograms$ ./swap 123 456
    i = 123 j = 456. Later, i = 456 j = 123
    Now try it in Java®
    campbell@campbellsComputer:~/CPrograms$ java IntSwap 123 456
    i = 123 j = 456. Later, i = ??? j = ???
    You will have to run it yourself to see the output
    The difference is because the handling of multiple assignments (what horrible code) falls foul of the left‑to‑right rule.

    By the way: you may be given that very same expression in an interview question. You now know the right answer.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!