Post Increment Infinite loop i += i++; [duplicate]
Asked Answered
U

3

10

I am not understanding why this post increment equation does not increase. I would have thought that after the += operation the value would increment by 1 and then the second time around i would have a 1 value. But the output is an infinite loop of 0 zero. Is anyone able to explain why 'i' doesn't increase.

int i = 0;
for(; ; ) {
  if ( i >= 10) break;
  i += i++;
}
System.out.println(i);
Utas answered 14/2, 2017 at 5:35 Comment(7)
As a side note, the behavior comes from how post-incrementation is defined and how the += operator works. The same behavior is observable in JS, and probably in other languages.Waterish
Java Puzzlers has a similar but slightly trickier puzzle called Inclement Increment.Archilochus
In Java and C# it outputs infinite loop. But in C it outputs like the code is : i += ++i; Changes from language to language.Fleshpots
@HasanAlperOcalan - I'd expect in C that it triggers undefined behaviour. Saying that "C does X" in this situation is probably wrong.Melmon
In C#: #13517189Selfinduced
And also #11432414 or the more general #2371618Selfinduced
Thank you for all the helpful replies. I understand now that it is the order of evaluation that changes the value back to 0 zero. I should have stated in the original question that this was from a practice test and I see it probably has no real use aside from being a trick question.Utas
R
6

While the answer from @njzk2 is correct, it is useful to point out why it is correct.

There are other possibilities - for example, why doesn't Java execute the postincrement operator after the assignment? (Answer: because that's not what the Java Language Designers chose)

The evaluation order for compound assignments (things like +=) is specified in the Java Language Specification section 15.26.2. I'll quote how it is defined for Java 8:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.

  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

The most important thing is that the value of the left hand expression is saved first, then the right hand is completely evaluated, and then the result of the compound operation is stored in the variable on the left hand side.

Reserve answered 14/2, 2017 at 6:27 Comment(2)
Correct, but pointless. This is one of the cases where UB is completely justified.Devonadevondra
@Devonadevondra You're probably referring to Undefined Behaviour (UB) in C. I disagree with your statement when it comes to Java. The philosophy of Java is to make it as cross-platform as possible. There is no totally undefined behaviour in Java, although there is some behaviour that can vary between platforms within the bounds of the specification. The design philosophy for C/C++ is different.Reserve
W
22

Let's examine i += i++;

i++ means read the value for i, then increment i.

i += x means evaluate i, then evaluate x and add the 2 and put the result in i.

So, what happens is:

  • i gets evaluated, it is 0
  • i++ gets evaluated. it returns 0, and the value for i is set to 1
  • i += i++ is now i = 0 + 0.
  • i = 0

Try with ++i to get the result of the incrementation before reading its value.

Waterish answered 14/2, 2017 at 5:41 Comment(0)
R
6

While the answer from @njzk2 is correct, it is useful to point out why it is correct.

There are other possibilities - for example, why doesn't Java execute the postincrement operator after the assignment? (Answer: because that's not what the Java Language Designers chose)

The evaluation order for compound assignments (things like +=) is specified in the Java Language Specification section 15.26.2. I'll quote how it is defined for Java 8:

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.

  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

The most important thing is that the value of the left hand expression is saved first, then the right hand is completely evaluated, and then the result of the compound operation is stored in the variable on the left hand side.

Reserve answered 14/2, 2017 at 6:27 Comment(2)
Correct, but pointless. This is one of the cases where UB is completely justified.Devonadevondra
@Devonadevondra You're probably referring to Undefined Behaviour (UB) in C. I disagree with your statement when it comes to Java. The philosophy of Java is to make it as cross-platform as possible. There is no totally undefined behaviour in Java, although there is some behaviour that can vary between platforms within the bounds of the specification. The design philosophy for C/C++ is different.Reserve
M
1

No surprise you are getting into infinity loop..

class Demo{
  public static void main(String[] args){
    int i = 0;
    for( ; ; ) {
        if (i >= 10) 
            break;
        i = i+i++;
        System.out.println(i);
    }
  }
}

assume the above code, I have just replaced your line with increment with what compiler will substitute.

Now, initially i=0; So

i = i+i++

results in i = 0 + 0 // and now i is 1

but at the end you again make i equal to 0!

Hence infinity...

Margretmargreta answered 14/2, 2017 at 6:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.