tags:

views:

1471

answers:

6

Given the following code, will ixAdd do what you'd expect, i. e. return the value of ix before the increment, but increment the class member before leaving the function?

class myCounter {
    private int _ix = 1;

    public int ixAdd()
    {
        return _ix++;
    }
}

I wasn't quite sure if the usual rules for post / pre increment would also apply in return statements, when the program leaves the stack frame (or whatever it is in Java) of the function.

+4  A: 

Yes it does.

soulmerge
But why bother paste the code on Stackoverflow when you could as well run it?
soulmerge
-1 Although he asked a yes or no question, you haven't done anything to actually explain it, which means the person ultimately doesn't know anything more than they did beforehand.
Yeah, I don't really know. Temporary eclipse in my brain? I still got nice answers, amazing.
Hanno Fietz
i agree. he could have tested it and then knew "yet it does" but he apparently was looking for more detailed information and a "why"
Johannes Schaub - litb
@litb I agree, understanding is a key to learning. I hate knowing yes or no, without understanding why the answer is what it is. Also... I just found this question by searching and found it useful. I'm certain others have as well.
Mark Renouf
+1  A: 

Yes, the usual rules apply for post increment even on a return statement. Basically, what it will do at a low level is store the return value into a register, then increment the class member, then return from the method.

You can see this in a later answer to this question that showed the byte code.

Eddie
+10  A: 

The key part is that a post increment/decrement happens immediately after the expression is evaluated. Not only does it happen before the return occurs - it happens before any later expressions are evaluated. For instance, suppose you wrote:

class myCounter {
    private int _ix = 1;

    public int ixAdd()
    {
        return _ix++ + giveMeZero();
    }

    public int giveMeZero()
    {
        System.out.println(_ix);
        return 0;
    }
}

That would print out the incremented result as well, because the increment happens before giveMeZero() is called.

Jon Skeet
Thanks for the answer, Jon. As Paul Tomblin pointed out, typing the code in my editor instead of the post would have answered it, too. But now I got more out of it than I asked for.
Hanno Fietz
@Jon: For people coming from C to Java (which will be a lot of people), this is a good thing to point out. As a long time Java user who first used C for a long, long time, I didn't know that Java defined how ++ works so much more clearly than C does. I learned to avoid "clever" ++ use from C!
Eddie
A: 

Yes, it does.

But don't do that, it is bad style to have side effects in expressions.

starblue
The side effect here is very much intended and I can't see it do any harm.
Hanno Fietz
But it makes it hard to understand, as your question shows.
starblue
+6  A: 

Well, let's look at the bytecode (use javap -c <classname> to see it yourself):

Compiled from "PostIncTest.java"
class myCounter extends java.lang.Object{
myCounter();
  Code:
   0:   aload_0
   1:   invokespecial #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   iconst_1
   6:   putfield #2; //Field _ix:I
   9:   return

public int ixAdd();
  Code:
   0:   aload_0
   1:   dup
   2:   getfield #2; //Field _ix:I
   5:   dup_x1
   6:   iconst_1
   7:   iadd
   8:   putfield #2; //Field _ix:I
   11:  ireturn

}

As you can see, instructions 6 and 7 in ixAdd() handle the increment before the return. Therefore, as we would expect, the decrement operator does indeed have an effect when used in a return statement. Notice, however, that there is a dup instruction before these two appear; the incremented value is (of course) not reflected in the return value.

Michael Myers
Hey, that's probably more than the question deserved. Nice one!
Hanno Fietz
I like bytecode. :)
Michael Myers
A: 

It does return the value before the increment, and then increment _ix. Therefore the first time you call the method ixAdd on an instance of myCounter it will return 1, the second time it will return 2, and so on.

trilobite