a += a++;

Discussion in 'Java' started by Razvan, Aug 21, 2004.

  1. Razvan

    Razvan Guest

    Hi !





    The output of the following code

    a+= a++;
    System.out.println(a);

    .... is 4

    Shouldn't the output be 5 ?

    step 1: evaluate left operand (a == 2 )
    step 2: evaluate right operand (a++ which also gives 2)
    step 3: evaluate a = 2 + 2; => a == 4
    step 4: increment a (don't forget about the post increment operator)
    => a== 5


    It seems that the post increment operator result is lost.
    Why is this happening ? Could it be because the operator is applied
    BEFORE the final operation a = 2 + 2 ? That means there is an
    intermediate value of 3 that is overwritten with 4 when a= 2 + 2 ?
    Is this a good explanation ?



    Regards,
    Razvan
     
    Razvan, Aug 21, 2004
    #1
    1. Advertising

  2. On 21 Aug 2004 08:19:09 -0700, (Razvan) wrote:

    >Hi !
    >
    >
    >
    >
    >
    > The output of the following code
    >
    >a+= a++;
    >System.out.println(a);
    >
    >... is 4
    >
    > Shouldn't the output be 5 ?


    I think the explanation is that
    a += a++;
    is treated as
    a = a + a++
    which is evaluated left from right:
    step 1: a = 2 + a++; //a==2
    step 2: a = 2 + 2; //a==3
    step 3: a = 4; //a==3
    step 4: //a==4
     
    Ole Ildsgaard Hougaard, Aug 21, 2004
    #2
    1. Advertising

  3. Razvan

    Superdude Guest

    Razvan wrote:

    > Hi !
    >
    >
    >
    >
    >
    > The output of the following code
    >
    > a+= a++;
    > System.out.println(a);
    >
    > ... is 4
    >
    > Shouldn't the output be 5 ?
    >
    > step 1: evaluate left operand (a == 2 )
    > step 2: evaluate right operand (a++ which also gives 2)
    > step 3: evaluate a = 2 + 2; => a == 4
    > step 4: increment a (don't forget about the post increment operator)
    > => a== 5
    >
    >
    > It seems that the post increment operator result is lost.
    > Why is this happening ? Could it be because the operator is applied
    > BEFORE the final operation a = 2 + 2 ? That means there is an
    > intermediate value of 3 that is overwritten with 4 when a= 2 + 2 ?
    > Is this a good explanation ?
    >
    >
    >
    > Regards,
    > Razvan



    As per the specification:

    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.
    Before the addition, binary numeric promotion (§5.6.2) is performed on
    the value 1 and the value of the variable. If necessary, the sum is
    narrowed by a narrowing primitive conversion (§5.1.3) to the type of the
    variable before it is stored. The value of the postfix increment
    expression is the value of the variable before the new value is stored.
     
    Superdude, Aug 21, 2004
    #3
  4. Razvan

    Chris Smith Guest

    Razvan wrote:
    > step 1: evaluate left operand (a == 2 )
    > step 2: evaluate right operand (a++ which also gives 2)
    > step 3: evaluate a = 2 + 2; => a == 4
    > step 4: increment a (don't forget about the post increment operator)
    > => a== 5


    Revise that as follows:

    > step 1: evaluate left operand (a == 2)
    > step 2a: evaluate right operand (a++ which also gives 2)
    > step 2b: as a side effect of step 2, increment a (a == 3)
    > step 3: add the left and right operands (2 + 2 = 4, a still == 3)
    > step 4: assign the result to a (a == 4)


    So the change made to a in step 2b is overwritten in step 4. The
    important thing to note is that step three adds the previously computed
    results of the expressions 'a' and 'a++', NOT the current value of the
    'a' variable. (Also note that steps 2a and 2b are not strictly
    sequential; that's just a model for the predicted outcome.)

    Here are a few other expressions to think about and check your
    understanding:

    a = (a++) + a;
    a = a * (a++);
    a = (a++) * a;

    > Could it be because the operator is applied
    > BEFORE the final operation a = 2 + 2 ? That means there is an
    > intermediate value of 3 that is overwritten with 4 when a= 2 + 2 ?
    > Is this a good explanation ?


    Yes., that's a perfect explanation. The increment happens at the same
    time the post-increment expression is evaluated, which is *before* the
    assignment is evaluated. The post-increment (versus pre-increment) only
    changes the RESULT of the expression; it makes no difference as to when
    'a' is incremented. Unfortunately, the operator names confuse people a
    bit.

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Aug 21, 2004
    #4
  5. Razvan

    Cid Guest

    On 21 Aug 2004 08:19:09 -0700, (Razvan) wrote:

    >a+= a++;
    >System.out.println(a);
    >
    >... is 4
    >
    > Shouldn't the output be 5 ?
    >
    >step 1: evaluate left operand (a == 2 )
    >step 2: evaluate right operand (a++ which also gives 2)
    >step 3: evaluate a = 2 + 2; => a == 4
    >step 4: increment a (don't forget about the post increment operator)
    >=> a== 5
    > It seems that the post increment operator result is lost.
    >Why is this happening ? Could it be because the operator is applied
    >BEFORE the final operation a = 2 + 2 ? That means there is an
    >intermediate value of 3 that is overwritten with 4 when a= 2 + 2 ?


    I'm not really clear on the javap bytecode instructions syntax yet.
    Here's the disassembly of your scenario though (pre a=2, post:a=4):

    0: iconst_2
    1: istore_1
    2: iload_1
    3: iload_1
    4: iinc 1, 1
    7: iadd
    8: istore_1

    We need somebody versed in the VM spec
    http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html
    at this point.

    Perhaps its significant that there is not istore_1 between the iinc
    and iadd instructions. If each op writes to a temporary 'register'
    that doesn't get saved until your store it then the iinc might be
    getting lost. I'm just guessing. Wait for a VM guru to come along, or
    look it up yourself in the VM spec (link above).
     
    Cid, Aug 21, 2004
    #5
  6. (Razvan) writes:

    > step 1: evaluate left operand (a == 2 )


    No, assignment operator has lowest precedence here. The whole
    expression is evaluated, not just left to right but according to
    precedence rules.

    > step 2: evaluate right operand (a++ which also gives 2)


    This is done first, yes. After this, a has the value 3.

    > step 3: evaluate a = 2 + 2; => a == 4


    Correct.

    > step 4: increment a (don't forget about the post increment operator)


    No, the assigment expression happens after the increment one. In Java,
    this is well-defined, unlike, say, in C.
     
    Tor Iver Wilhelmsen, Aug 22, 2004
    #6
  7. Superdude <> writes:

    > 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.


    Not relevant, though: §14.1 says "The only reason an expression can
    complete abruptly is that an exception is thrown" - and none is thrown
    here.

    The reason a = 4 is that the statement (the complete expression) ends
    with an assignment (last part-expression evaluated) of the sum (third
    expression) of a and a++ (first and second expressions both yielding
    the same value even though the latter lets a have the incremented
    value until the last assignment) to a.

    The OP needs to consider than for operations, the values are _copied_
    on the stack, and that evaluation is not left to right but accodring
    to precedence rules, left to right only coming into play when the
    precedence is the same. Consider expressions to be parsed into a tree,
    which is evaluated depth-first. In this case, something like

    (=)
    / \
    a (+)
    / \
    a (x++)
    |
    a
     
    Tor Iver Wilhelmsen, Aug 22, 2004
    #7
  8. On 21 Aug 2004 08:19:09 -0700, Razvan <> wrote:

    > Hi !
    >
    >
    >
    >
    >
    > The output of the following code
    >
    > a+= a++;
    > System.out.println(a);
    >
    > ... is 4
    >
    > Shouldn't the output be 5 ?
    >
    > step 1: evaluate left operand (a == 2 )
    > step 2: evaluate right operand (a++ which also gives 2)
    > step 3: evaluate a = 2 + 2; => a == 4
    > step 4: increment a (don't forget about the post increment operator)
    > => a== 5
    >
    >
    > It seems that the post increment operator result is lost.
    > Why is this happening ? Could it be because the operator is applied
    > BEFORE the final operation a = 2 + 2 ? That means there is an
    > intermediate value of 3 that is overwritten with 4 when a= 2 + 2 ?
    > Is this a good explanation ?
    >
    >
    >
    > Regards,
    > Razvan


    As an academic exercise, a discussion of this is perhaps justifiable. But
    whoever writes codes like this in the real world should be shot (or at
    least fired).
     
    Richard Chrenko, Aug 23, 2004
    #8
  9. Razvan

    Razvan Guest

    > As an academic exercise, a discussion of this is perhaps justifiable. But
    > whoever writes codes like this in the real world should be shot (or at
    > least fired).


    Naturally, it is an academic discution.



    Regards,
    Razvan
     
    Razvan, Aug 25, 2004
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page