Results 1 to 19 of 19
  1. #1
    kssu1967 is offline Member
    Join Date
    Jul 2009
    Posts
    3
    Rep Power
    0

    Default postincrement in java

    i want to know the reason, why is the following java code giving the output 10 instead of 11 as expected.
    class a
    {
    public static void main(String args[])
    {
    int i=9;
    i=++i;
    i=i++;
    System.out.println(i);
    }
    }

  2. #2
    kssu1967 is offline Member
    Join Date
    Jul 2009
    Posts
    3
    Rep Power
    0

    Default

    expecting quick reply. thank you.

  3. #3
    mtyoung is offline Senior Member
    Join Date
    Dec 2008
    Location
    Hong Kong
    Posts
    473
    Rep Power
    6

    Default

    ++i increase before assign
    i++ increase after assign

    so
    i = ++i => i = i + 1
    i = i++ => i = i

  4. #4
    kssu1967 is offline Member
    Join Date
    Jul 2009
    Posts
    3
    Rep Power
    0

    Default post increment in java

    thank you for your reply. logically after the second assignment statement it has to be incremented before the println statement. but it has not been giving the incremented answer. but previous value.

    i=9;
    i=++i =>10;
    i=i++ =>10;
    system.out.println(i);=> 10 instead of 11.

    what is the reason?

    thank you.

  5. #5
    adz
    adz is offline Member
    Join Date
    Jul 2009
    Posts
    35
    Rep Power
    0

    Default

    Simple really.

    i = i++ is the same as this:

    int old = i;
    i = i+ 1;
    i = oldValue;

    This is because i++ is first evaluated, giving the value of i before incrementation. i is then incremented by one. And then i is set the value of i++ (which as the first sentence says, is the value before incrementation).

    should be i++ and no i = i++.

    But anyway, that's the reason why it isn't 11.

  6. #6
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    I'm having the same problem as kssu1997. Here's the problem:
    int i = 10;
    int j;
    j=i++;
    System.out.println(i);
    System.out.println(j);
    prints 11 and 10 as I would expect, fully understanding the effect of the postincrement instruction.

    Now, lets examine the sequence:
    i=10;
    i=i++;

    What this statement says is move 10 into storage location i, move the variable at storage location i into storage location i, increment storage location i.
    IMHO, i should be incemented. I coded this up. It doesn't work that way, i remains 10.
    i should be incremented after the assignment statement, and isn't.
    I would expect the sequence i = i++; to be equivelent to
    i=i leaving i = 10
    i = i + 1; leaving i =11;

    The previous postings about the effects of postincrement explain why the value of 10 is assigned to j, or i depending on how it is coded, but in one case i is incremented, in the other not. There's more going on that needs to be explained.

    EDIT:

    I just coded the problem in C++.
    The complete program is basically
    main(argv, argc) {

    int i=10;
    i++;
    return

    }

    i has the value of 11 after the completion of the i++ statement.

    Edit2: I'm like a dog with a bone. Mulling over the observation about coding the statemnet i=i++ as simply i++; This does work as it is supposed to and I will allow that i=i++; is a bit redundant and probably poor style. Maybe just best to call it FM (f----n magic);
    Last edited by rdtindsm; 07-29-2009 at 05:13 AM.

  7. #7
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    It's not magic. "i++;" and "i=i++;" mean two very different things.

    "i++;" is an expression with a side effect. The expression has the value of i. And the side effect is that after the expression is evaluated i is incremented.

    Step by step we have:
    int i = 10; // i is assigned the value 10
    i++; // the expression is evaluated have the value 10. the side effect increments i so it ends up assigned the value 11.

    "i=i++;" starts off the same. The right hand side is an expression with a value (10) and a side effect (i is incremented). Then the value of the right hand side expression is assigned to i. Read that previous sentence again: the value of i is not assigned to i (with or without memory locations entering into it), 11 is not assigned to i. The value of the right hand side expression (10) is assigned to i.

    [Edit]
    And the reason we don't write "i=i++;" is not that it's redundant: it's that it's pointless to increment i (which is what the rhs does as a side effect) and then immediately assign i it's old value (which is what the assignment does). Pointless and probably wrong, since "i++;" is most likely what was meant.
    The steps are conceptually as adz posted above.
    Last edited by pbrockway2; 07-29-2009 at 07:33 AM.

  8. #8
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    I know we are going to go around and around on this, and that is exactly why I wrote the C code. In that environment, I wouldn't write i=i++; because it is both, redundant and pointless, but not incorrect. But but the statement does not leave the old value (10) in i, it leaves a new value (11) in i, what I would have expected a priori, and what the original poster was expecting in his JAVA code.

    Read your explanation carefully. I think that what you meant to say is:
    The right hand side is an expression with a value (10). The value of the right hand side expression is assigned to i. As a side effect, i is incremented after the assignment is carried out.

    I am expecting to see the side effect that i is incremented, not simply the value of i. i is incremented in the expression j=i++; as a "side effect", and we see the effect in a println statement. If it is merely the VALUE of i that is incremented, then the single statement i++ is meaningless without an assignment statement.

    Memory locations do enter in to the understanding. The variable i is translated into machine language as a relative memory address using a combination of hardware registers (stack pointer or heap location) to calculate the address, but there is a one to one correspondence. I fully understand that the value initially assigned to i is 10. The whole problem is that the ++ side effect of the expression i++ is not happening.

    The machine code (or for Java, virtual machine code) should look something like this using j and i and j=i++;
    mov j,i #j = 10, i = 10
    inc i # side effect, i=11

    Note that it is not the value of i, but the contents of i that is being transferred, and it is the contents, not the value of i that should be incremented.

    all we need to do in the expression i=i++ is change the mov j,i to mov i,i;
    This may not make a lot of sense, I haven't looked at a reference of any processor, and it is of course processor dependent at this level, to see if this is allowable code. But the whole purpose of the JVM is to separate the Java code from machine code. An optimizing compiler might just eliminate the mov i,i instruction , but i still needs to be incremented. That's what i++ means. Every time, not just contextually.

    It is also irrelevant as to whether it is the VALUE of i, or the CONTENTS of i that is assigned to i. At the point that the increment is processed, both are 10. I don't find the explanations I'm reading to be internally consistent. I can only quote

    "And the side effect is that after the expression is evaluated i is incremented. "

    This whole discussion is because i is in fact not being incremented after the expression is evaluated and assigned. It's the same variable, and should be in the same memory location. You've explained why j=i++; would be 10, but not why i=i++; is not 11.

    Realizing that Java is not C and can implement similar statements different ways, Java syntax is purposely very similar to C/C++. To implement the JAVA statement differently causes problems for people fluent in both languages. And I have to reiterate that we are simply not seeing the explicit side effect that i is incremented. Post or pre incrementing shouldn't have any different result once the whole line is processed.



    If this is a correct implementation of the Java standard, realizing that the standard may or may not cover this situation, I personally and strongly feel that the standard or the implementation needs to be changed.

  9. #9
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    OK, one more go around examining how post increment works, and timing of updates.
    i=10, hoping for more understanding of the problem. The following was evaluated in JAVA:
    i = i++ + i; -> 21
    i has the value 10, i is incremented, the second expression of i is now 11 and added to the initial value of i before the increment.
    Resulting i = 21, what I expected.

    i = i + i++;
    This expression yields 20 in JAVA, 21 in C++.
    While this expression could be written in other ways, it is not incorrect, and is in no way pointless As an addition, it would execute faster than (2*i)+1, perhaps a correction that an optimizing compiler would make.

    Texts generally spend some time examining how and when pre and post increment instructions work; these question are questions that will likely be seen on end of chapter reviews and fair game for tests, possibly a pre-employment test. Texts spend some amount of time showing how the process works evaluating e.g. conditionals. The process and the timing of the pre and post increment statement should (must) be well understood by any student who has covered the material.

    I can only reiterate that JAVA in the example code is not incrementing the variable at all, anywhere, anytime, despite quite explicit code to do so. IMHO, I see this as a serious flaw in the implementation, and a serious problem in porting code.

    Do you really want to reexamine every instance of the post increment to see if correct C/C++ code is going to work in the JAVA environment? I surely hope that JAVA is not being used in mission critical settings. A space probe missed Mars because somebody forgot to convert km to/from miles, despite the rigorous testing of the space program. Or perhaps you're in the ICU hooked up to life support and the alarm fails to sound. These things happen. Rots of Ruck.

    PS: I've previously posted code regarding the implementation of the post-increment in assembly. On some consideration, I realize that the example is simply a way it could be done, not the way it is or should be done, most certainly not gods own truths. (Punctuation is deliberate; am willing to allow for different truths by Shiva, a bhudda, or Allah).
    Last edited by rdtindsm; 07-29-2009 at 07:43 PM.

  10. #10
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    > Read your explanation carefully. I think that what you meant to say is:
    > The right hand side is an expression with a value (10). The value of the right hand side
    > expression is assigned to i. As a side effect, i is incremented after the assignment is
    > carried out.

    This is about a situation like:

    Java Code:
    int i = 10;
    i = i++;
    System.out.println(i);
    No - I was trying to describe what really does happen. If i were incremented after the assignment was carried out then we would see that incremented value (11) being printed. And we don't.

    So I'll stick with: The right hand side is (A) an expression with a value (10) and (B) a side effect (i is incremented). (C) Then the value of the right hand side expression is assigned to i. A-B-C in that order.

    See JLS 15.14.2 for why the rhs expression has the value 10. "The value of the postfix increment expression is the value of the variable before the new value is stored." And how, at runtime, this evaluation is accompanied by a side effect "the value 1 is added to the value of the variable and the sum is stored back into the variable."

    (JLS 14.8 explains how in the case of an expression statement like "i++;" the value of the expression is simply discarded. This section makes the interesting point that "i++" is something of an exception: in general Java expressions are not statements.)

    Once the RHS expression has been evaluated (to 10 as mandated by 15.14.2) we are in a position for the assignment statement to be carried out. That assignment is carried out with the effect reported by the println() statement. (the statement involves an assignment expression whose value is discarded.

    Bottom line: it's a post increment in the sense of after the evaluation of the expression of which it's part. Not after the larger statement of the which the expression might be a part.

    (I'm not really addressing byte code/memory - of which I'm ignorant. Or the "serious flaw" business, except to say that I would hope the programmers who worked on life support software attached to me, put aside any a priori nostrums and clung closely to the language as specified in the JLS. Others might find these aspects of the problem interesting.)
    Last edited by pbrockway2; 07-30-2009 at 12:33 AM.

  11. #11
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    It is interresting to read the reference that pbrockway2. Perhaps the key is in the phrase:

    "At run time, if evaluation of the operand expression completes abruptly, then the postfix increment expression completes abruptly for the same reason and no incrementation occurs. Otherwise, the value 1 is added to the value of the variable and the sum is stored back into the variable."

    Can anybody explain the phrase "operand expression completes abruptly". Evidently there is no subsequent assignment because the operand expression has completed abruptly.

    These phrases indicate that an incremented value of i is created (in some other location than the actual variable), and this value is subsequently assigned to i. This explanation clearly explains why i++ works.

    I think we both understand that the value of i is assigned before the increment. That is why i = i++ + i evaluates correctly in both Java and C. One of my big hangups is that C evaluates the expression in a different way than JAVA, and in the way that I consider proper. Yes, the JAVA coders should be coding to the JAVA standard; my point is that the similarity of JAVA to C can understandably lead to confusion by developers that are used to C/C++. The two environments create different answers for the same arithmetic expression. This is at best disconcerting and can lead to larger problems. I don't think the best answer is merely to state that we should get rid of preconceived notions about how things should work.

    The statment that a new value is created makes any explanation that I provided about registers a bit moot by making the distinction between the value and the variable. It is not the variable that is incremented, but the value. But I already tried to allude to this problem by retrenching on statements about storage.

  12. #12
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    An example of the operand (postfix) expression completing abruptly would be:

    Java Code:
    Integer foo = null;
    foo++;
    In terms of 15.14.2 "foo++" is a valid PostIncrementExpression. That's because "foo" - the PostfixExpression - is convertible to a numeric type as described in 5.1.8 (Unboxing conversions). But in the course of evaluating that PostfixExpression ("foo") somethig nasty happens and we get an abrupt completion (aka an exception being thrown). In such cases 15.14.2 is saying that the side effect incrementing of "foo" won't be attempted.

    > I think we both understand that the value of i is assigned before the increment.

    Not me. Or JLS 15.14.2.

    in situations like

    [code]
    int i = 10;
    i = i++;
    [code]

    A) i++ is evaluated (provided converting i to a numeric type doesn't lead to an abrupt completion), yielding the value 10.

    B) The side effect causes i to be incremented.

    C) The assignment of i++'s value (10, as determined in step A) is assigned to i.

    Java Code:
    int i = 10;
    i = i++ + i;
    In this code 21 is assigned to i. The value 21 is evaluated by working through the + operands left-to-right: i++ is evaluated to be 10 as before. The second operand is found to be 11 because of the first operand's side effect increment of i. And the sum is 21=10+11 which is assigned to i. The postfix increment is not pointless here because it has an observable effect on the second operand of the addition.

    Java Code:
    int i = 10;
    i = i++ + 10;
    This works the same way, but now 20=10+10 is assigned to i. The side effect increment still happens, but it is pointless in as much as the new value of 20 is then assigned to i.

    "i=i++;" is extremely similar to this case - it's just "i=i++ + 0;"

    ----

    Since comparison with C keeps coming up here, can anyone say (with references) what expressions like "i=i++;" are supposed to mean in that language? My understanding was that "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression." But that was way back when we just said "no" to such abominations. Maybe the rules have change since then...

  13. #13
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    I've just noticed a few posts back the variation:

    Java Code:
    int i = 10;
    //i = i++ + i;
        // the very different sum
    i = i + i++;
    Here, because - in Java - operation order is strictly left-to-right, the increment side effect occurs after the sum's first operand is evaluated. And it is the resulting sum 20=10+10 that is ultimately assigned to i when that second expression is evaluated.

    Again, as to the claim that this yields an assignment of 21 to i in C++, can anyone provide a reference supporting this claim?

  14. #14
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    The result is undefined in c/c++. Different compilers produce different resuts.
    I just came a cross this the other day:
    Java Code:
    #include<stdio.h>
    
    void call(int x,int y,int z){
      printf("%d %d %d",x,y,z);
    }
    
    void main(void){
      int a=10;
      call(a,a++,++a);
    }
    tried it on gcc, bcc, tcc and got different results. But on java, its always the same.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  15. #15
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    My assertion that i=i++; -> 11 and i= i + i++; -> 21 was based on coding the problem in Visual Studio. I just coded the problem in gcc and g++, getting the same result. angryboy has posted an interesting experiment that shows that there can be and are ambiguities in implementing standards. Would be interested in seeing results. I will code it; I'm not sure what I would expect.

    Even accepting that JAVA standards are correctly implemented in the phrase i=i++; or that there permissible differences in implementing the handling, I guess that I would still make the argument that gcc is incredibly mature and provides a precedence that would be well to follow.

    I've perhaps been a bit arrogent in the past that is not justified by my own infallibility. I apologize. At this point, I'm simply trying to find what is happening and to clarify misunderstandings in a way that I find internally consistent. I at least find the results from the c compilers consistent with any explanation I've read about the use of postincrement.

    We sometimes use phrases that are ambiguous, that might be interpreted in ways that we know correctly, but express inaccurately.

    One problem that I have in reading explanation is the phrase "evaluates i++". The expression has a time factor and, to me, i++ is the value after the increment. It would make more sense if the the meaning were "the compiler parses and evaluates the expression i++". And I keep getting hung up with the question "What happens to the incremented value of i that is the side effect?".

    I also don't find "side effect" to be well defined. A side effect is a write to the screen, it might even be the creation of a temporary variable, but would be something that is affected by the task at hand without changeing the state of task. The phrase means something different to me than if evidently does to pbrockway2.

    The other problem in terminology that I find confusing is the phrase
    "The side effect causes i to be incremented."
    The JLS indicates that the VALUE of i is copied and incremented, that this value is then later moved to the contents of i. I read the quoted phrase as referring to the actual storage location of i, that is, a reference, not a value. In this case, the distinction between the value of i and the use of i as an alias for a storage address needs to be made.
    Last edited by rdtindsm; 07-30-2009 at 06:37 PM.

  16. #16
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    There's to need to apologise!

    It's reasonable to want to see the sense or logic behind the semantic interpretation of any construction. (It allows you to remember things better. And it gives you someway to uzzle your way through novel situations.) But sometimes there isn't any sense: why drive on the left hand side of the road? (or not, depending on locale). And always, it seems to me, it's a good idea to start with what happens rather than variations on why it should(n't).

    That's why I've been stressing that the expression "i=i++" involves evaluate-increment-assign and not evaluate-assign-increment. Java drives on that side of the road.

    The JLS ultimately defines the Java language and it does so i terms of what expressions do with relatively little to say about how or why. You're right: 15.14.2 doesn't talk about "side effect" or "incrementing" or "evaluate" for that matter. But it is clear that the expression "i++" is supposed to have the value 10, that 1 is to be added to the value of "i" and the result stored back into i.

    The opening part of Chapter 15 gives some Java "side of the road" rules that mandate left-to-right evaluation of operands (and arguments in a method invocation) and evaluation of operands before the operation. The first of these allows a clear separation between what happens in "i + i++" and "i++ + i". And the second directly addresses the increment coming before the assignment operation in "i=i++".

    AngryBoy's example is similar to what I remember being confused about a long time ago when I had written (I think)

    Java Code:
    cout << i++ << i++;
    I knew what I meant and thought it was unambiguous. (and certainly defined.) When I acquired a computer with a different OS and compiler, I found out I was wrong.

    I mention this because I think the business of comparing Java to C++ can also be approached in terms of "what" rather than "which is better". It turns out that it's not so much that Java gives one result and C++ another: rather Java defines side effect behaviour in situations where C++ chooses not to.

    The "life support software" argument begins to take on a different aspect. If it were Java software and included "i=i++;", I'd think it was pretty weird. If it were C++ software and included that line, ... I'd sue for malpractice! The author may well think his or her compiler is very cool and the language should be redesigned according to its lights. But the fact remains that the effect of such code is undefined.
    Last edited by pbrockway2; 07-31-2009 at 12:01 AM.

  17. #17
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,044
    Rep Power
    20

    Default

    Quote Originally Posted by rdtindsm View Post
    One problem that I have in reading explanation is the phrase "evaluates i++". The expression has a time factor and, to me, i++ is the value after the increment. It would make more sense if the the meaning were "the compiler parses and evaluates the expression i++". And I keep getting hung up with the question "What happens to the incremented value of i that is the side effect?".

    The other problem in terminology that I find confusing is the phrase
    "The side effect causes i to be incremented."
    The JLS indicates that the VALUE of i is copied and incremented, that this value is then later moved to the contents of i. I read the quoted phrase as referring to the actual storage location of i, that is, a reference, not a value. In this case, the distinction between the value of i and the use of i as an alias for a storage address needs to be made.
    Probably help to look at the byte code.

    Java Code:
        0  bipush 10
        2  istore_1 [i]
        3  iload_1 [i]
        4  iinc 1 1 [i]
        7  istore_1 [i]
    The above is the code for:

    Java Code:
    int i = 10;
    i = i++;
    So, 0 and 2 set i to 10.
    Then we evaluate the controversial line...i is loaded up (iload), putting the value of i to one side (10). i is then incremented (iinc). Then i is set to the value stored earlier (istore).

    This is the side effect they are referring to...i is incremented, but it is a meaningless thing (unless threading comes into it) since it is then overwritten by the earlier value of i.

  18. #18
    rdtindsm is offline Member
    Join Date
    Feb 2009
    Posts
    92
    Rep Power
    0

    Default

    post retracted
    Last edited by rdtindsm; 08-03-2009 at 06:11 PM.

  19. #19
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,044
    Rep Power
    20

    Default

    Quote Originally Posted by rdtindsm View Post
    post retracted
    Oh....phooey.
    :)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •