Java post-increment (++) not behaving as expected when passed as a parameter
Asked Answered
F

4

8

I came across the following issue:

private void doStuff(int i) {
   if(i>10) {
      return;
   }
   doStuff(i++); 
}

public void publicMethod() {
   doStuff(i);
}

I would expect this to run doStuff 10 times and then return.

However i++ does not get executed before the doStuff is called again with 0.

Result is an infinite loop. I know how to fix it but I am wondering if this behaviour is correct or a bug.

Fulsome answered 12/10, 2012 at 13:24 Comment(2)
It is expected behaviour when you use post incrementationCordellcorder
...and you will get what you expect if you use doStuff(++i) instead.Review
D
23

Now I would expect this to run doStuff 10 times and then return, however i++ does not get execute before the doStuff is called again with 0.

Yes, the result of the post-increment operator is the original value... and then inside the next call to the method you've a new i. So in other words, this call:

doStuff(i++); 

is equivalent to:

int original = i;
i = original + 1;
doStuff(original);

From JLS section 15.14.2:

The value of the postfix increment expression is the value of the variable before the new value is stored.

Given that you don't use i again afterwards (and thus any side-effect on it is pointless), why not just simplify your life?

doStuff(i + 1);

(As with all parameters in Java, you're seeing pass-by-value - changing the value of i in the method does not change the value of the caller's argument.)

Denotative answered 12/10, 2012 at 13:26 Comment(4)
+1 or doStuff(++i); would work but is not as good an option.Schwann
Why is i + 1 a better option than ++i? Readability?Bing
@DavidGrant: Yes - you don't need to think about any ordering. The side-effect on the value of i is pointless, so why bother with it at all?Denotative
@JonSkeet "pass-by-reference"? Did you intend to say "pass-by-value"?Review
U
4

It behaves as expected it should, you probably want to replace i++ with ++i.

Check the oracle documentation on how to use the prefix/postfix unary increment operator:

class PrePostDemo {
    public static void main(String[] args){
        int i = 3;
        i++;
        // prints 4
        System.out.println(i);
        ++i;               
        // prints 5
        System.out.println(i);
        // prints 6
        System.out.println(++i);
        // prints 6
        System.out.println(i++);
        // prints 7
        System.out.println(i);
    }
}

(excerpt from the linked page)

Usk answered 12/10, 2012 at 13:26 Comment(3)
Well as I wrote, I know how to fix it just like you pointed out ++i, but I am a bit surprised. I would have expected it to perform the operation first and then make the call.Fulsome
@dngfng: It increments i before it makes the call, but the argument to the call is the original value of i.Denotative
@JonSkeet, indeed.. i've just fixed it. :-)Leacock
A
2

The ++ operator works just as expected. it first returns the value of the variable, and then increases the variable, hence you always pass 0.

This:

doStuff(i++);

is like:

int x = i;
i += 1;
doStuff(x);
Ainslee answered 12/10, 2012 at 13:26 Comment(0)
U
1

i++ means that: "use value of i and then increment it". It will always be zero when passed down. It is a value type, not a reference type. If that would be an object, that would be no problem because it would be handled as reference.

Unnecessarily answered 12/10, 2012 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.