Precedence of ++ and -- operators in Java
Asked Answered
J

9

11

I read from the official tutorial of Java that prefix and postfix ++ -- have different precedences:

postfix: expr++ expr--

unary: ++expr --expr +expr -expr ~ !

Operators

According to the tutorial, shouldn't this

d = 1; System.out.println(d++ + ++d);

print out 6 (d++ makes d 2, ++d makes it 3) instead of 4?

I know the explanation of ++d being evaluated beforehand, but if d++ has higher precedence then ++d, why isn't d++ being first evaluated? And what is more, in what case should d++ shows that it has higher precedence?

EDIT:

I tried the following:

d = 1; System.out.println(++d * d++);

It returns 4. It seems that it should be 2*2, instead of 1*3.

Joannejoannes answered 16/6, 2011 at 14:58 Comment(5)
Questions like this frustrate me immensely. Nobody ever writes code like System.out.println(d++ + ++d); so why do you care? Its a super-triviality.Phyllida
@Phyllida Though no one might ever write code like this, perhaps it's for school. Teachers/professors love asking these kind of "it'll never be written like this but we're ganna test you on it anyways to see if you understand how it works" questions.Clypeate
@Phyllida Sorry for frustrating you:) As for the reason why I asked, maybe it is because curiosity. Lucky me since I am no cat.Joannejoannes
@Kevin Teachers may love it but I can assure you this would get bounced back from code review anywhere outside of a classroom.Phyllida
There is no postfix-notation here. It is all infix. There are postfix operators.Kazukokb
C
16

The inside of the println statement is this operation (d++) + (++d)

  1. It is as follows, the value of d is read (d = 1)
  2. current value of d (1) is put into the addition function
  3. value of d is incremented (d = 2).

  4. Then, on the right side, the value of d is read (2)

  5. The value of d is incremented (now d = 3)
  6. Finally, the value of d (3) is put into the addition function

    thus 1 + 3 results in the 4

edit: sorry for the format, I'm rather bad at using the list haha

Clypeate answered 16/6, 2011 at 15:2 Comment(1)
Thank you for being the first replied and enlightened me! However, I used up my max upvote today, so I guess I would have to do it tomorrow. :)Joannejoannes
S
12

The key is what is returned from the operation.

  • x++ changes the value of x, but returns the old x.
  • ++x changes the value of x, and returns the new value.
d=1
System.out.println(d++ + ++d); // d is 1
System.out.println(1 + ++d); // d is 2
System.out.println(1 + 3); // d is 3

Prints 4

Stratfordonavon answered 16/6, 2011 at 15:3 Comment(0)
H
9

Higher precedence does not mean will be evaluated first.

It means the expressions will be grouped in this way.

In this case, d++ + ++d will be grouped as (d++) + (++d), and this binary expression will be evaluated in this order:

  • left operand d++. This subexpression consists of a postfix increment operator and a variable, so it has those two effects:
    • The subexpression's value is 1
    • the variable is updated: d = 2
  • right operand ++d. This subexpression consists of a prefix increment operator and a variable, so it has those two effects:
    • The variable is updated: d = 3
    • The subexpression's value is 3
  • operator + is evaluated, using the values of the two operands.
    • Thus the expression value is 1 + 3 = 4.

The different precedence between the prefix and postfix forms of ++ would only be seen in ++d++, which will be interpreted as ++(d++) – and this has no meaning ((++d)++ has none, either), since ++ only works on variables, not on values (and the result is a value).

Harquebusier answered 16/6, 2011 at 15:8 Comment(6)
Close, but your conclusion is incorrect. It should be 1 + 3 = 4 as explained in the answers above. ++d returns the result before the increment, so although d will equal 2 after the left expression is evaluated, the left expression evaluates to 1.Chlamydeous
Thanks for the correction ... Strange that this got unnoted for 9 months.Weidman
You're welcome! I thought it was valuable to have this explained in so many different ways here, and I think many people will find the way you presented the information helpful.Chlamydeous
What confuses me is that all the answers google has led me to about this question talk as if "d++" and "++d" are operands. But, the Java Language Specifciation calls them prefix and postix operators. if operands are evaluated left to right, and THEN operators are applied, then (d++) + (++d) will, after evaluation of the two operands, will be ( (1)++ ) + (++(1)) -- which makes no sense to me. (what does 1++ even mean?). so, i would like to see an expanation on exactly what operands and operators get evaluated when, considering that each ++ is an operator themselves.Linter
@Linter The expressions ++d and d++ are both operands to the + operator here. Themselves they both are composed of an operator ++ (a prefix and a postfix one) and its operand d. We have a recursive expression structure.Weidman
@PaŭloEbermann thank you for the response! your edits do make things clearer. i'm not sure if i 100% understand evaluation order in java, but your edits give me another clue to think about.Linter
A
2

This is not about precedence, it's about evaluation order. d++ evaluates to 1, but then d is incremented. ++d increments d, and then evaluates to 3.

Amabelle answered 16/6, 2011 at 15:3 Comment(2)
I see. But could you show me a case in which the precedence is showed?Joannejoannes
@Ziyao: In an expression such as (3 - 4 * 5), precedence dictates that this is equivalent to (3 - (4 * 5)), not ((3 - 4) * 5).Amabelle
A
2

See Why is this Java operator precedence being ignored here?.

It boils down to the fact that the postfix operator is being evaluated first, but returns the original value of the variable, as designed. So, for the purposes of your operation:

(d++ + ++d)

Processes as:
1. d++ evaluates, returning the original value of 1 but incrementing d to 2
2. ++d evaluates, incrementing the value of 2 TO 3, and returning 3
3. +   evaluates, resulting in 1 + 3

The confusion is not in the order of precedence for the tokens to be evaluated, you've got that right. The real problem is in the understanding of the functional difference between the postfix and prefix operators.

Assassinate answered 16/6, 2011 at 15:7 Comment(0)
T
0

d has value 1

d++ is evaluated; it's value is 1 and d is now 2 (post++ returns value before increment)

++d is evaluated; it's value is 3 and d is now 3 (++pre returns value after increment)

1 + 3 = 4

Tenuis answered 16/6, 2011 at 15:4 Comment(0)
R
0

System.out.println(d++ + ++d);

Here's how it goes:

++d is executed, so d is now 2.

d + d is executed, which equals 4.

The value 4 is given to System.out.println()

d++ is executed, so now d is 3.

Runkel answered 16/6, 2011 at 15:5 Comment(0)
L
0

I went through all the explanations from top ..According to understanding following code should give 11.0 then y it gives 10.0 double x = 4.5; x = x + ++x; // x gets the value 10.0.

Lagasse answered 29/9, 2013 at 15:19 Comment(0)
L
-1

In addition to the other comments, I suggest you have a look at sequence points, as some of this stuff can lead to undefined behaviours, though I think your case is defined for java.

What does x[i]=i++ + 1; do?

http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html

Lynn answered 16/6, 2011 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.