Board index » jbuilder » weird incrementor question?

weird incrementor question?


2003-07-18 08:34:14 PM
jbuilder13
For studying for my SCJP exam, I read on some website to be careful about
the ++ operator and how it acts differently in the case where i = i++
doesn't produce what you would think. And it didn't. If you declare an int
i = 4, and then run the i = i++; at first I expected the value of i on the
next line to be a 5. Yes, due to the statement and the equals it's 4, but I
thought after the post incrementor kicks in, it would be 5. But no.
Take a look at the sample code here.
public class IncrementalTest {
public static void main(String[] args) {
int i = 4;
i = i++;
System.err.println("i=" + i);
int j = 5;
int k = 5;
j = k++;
System.err.println("j=" + j + "\t\tk=" + k);
//i=4
//j=5 k=6
}
}
I'm just wondering why does the i++ on the same line as the equals not
increment it? Does anyone have any ideas? Thanks.
 
 

Re:weird incrementor question?

I bet you read it in Marcus Green's tutorial ;-) I passed SCJP1.4 exactly 3
hours (!) ago so my knowledge of this subject is quite fresh :-)
Here is how it works: 1) all values of postfix incrementors are saved
somewhere (say in a "buffer");
2) all postfix incrementors are performed;
3) the entire expression is evaluated with saved values from the "buffer".
In your code:
int i = 4;
i = i++;
Here is what happens:
i's value is 4
1) i's value (4) is saved to a "buffer"
2) i is incremented (i==5)
3) a value from the "buffer" is assigned to i (i == 4).
That's it.
For prefix incrementors the steps 1 and 2 are swaped around. So, i = ++i
will assign 5 to i.
--Sultan
On Fri, 18 Jul 2003 08:34:14 -0400, Flip <[remove] XXXX@XXXXX.COM >
wrote:
Quote
For studying for my SCJP exam, I read on some website to be careful about
the ++ operator and how it acts differently in the case where i = i++
doesn't produce what you would think. And it didn't. If you declare an
int
i = 4, and then run the i = i++; at first I expected the value of i on
the
next line to be a 5. Yes, due to the statement and the equals it's 4,
but I
thought after the post incrementor kicks in, it would be 5. But no.

Take a look at the sample code here.

public class IncrementalTest {
public static void main(String[] args) {
int i = 4;
i = i++;
System.err.println("i=" + i);

int j = 5;
int k = 5;
j = k++;
System.err.println("j=" + j + "\t\tk=" + k);
//i=4
//j=5 k=6
}
}

I'm just wondering why does the i++ on the same line as the equals not
increment it? Does anyone have any ideas? Thanks.
 

Re:weird incrementor question?

Congrats on your passing! :>(I passed yesterday as well :>) The reference
sounds familiar, but I honestly forgot where I got it from, but did remember
the problem.
Thanks for the update. I thought it had to be something like that. Thanks
for the heads up.
"Sultanbek Tezadov" < XXXX@XXXXX.COM >wrote in message
Quote
I bet you read it in Marcus Green's tutorial ;-) I passed SCJP1.4 exactly
3
hours (!) ago so my knowledge of this subject is quite fresh :-)
Here is how it works: 1) all values of postfix incrementors are saved
somewhere (say in a "buffer");
2) all postfix incrementors are performed;
3) the entire expression is evaluated with saved values from the "buffer".
In your code:
int i = 4;
i = i++;
Here is what happens:
i's value is 4
1) i's value (4) is saved to a "buffer"
2) i is incremented (i==5)
3) a value from the "buffer" is assigned to i (i == 4).
That's it.
For prefix incrementors the steps 1 and 2 are swaped around. So, i = ++i
will assign 5 to i.

--Sultan

On Fri, 18 Jul 2003 08:34:14 -0400, Flip <[remove] XXXX@XXXXX.COM >
wrote:

>For studying for my SCJP exam, I read on some website to be careful
about
>the ++ operator and how it acts differently in the case where i = i++
>doesn't produce what you would think. And it didn't. If you declare an
>int
>i = 4, and then run the i = i++; at first I expected the value of i on
>the
>next line to be a 5. Yes, due to the statement and the equals it's 4,
>but I
>thought after the post incrementor kicks in, it would be 5. But no.
>
>Take a look at the sample code here.
>
>public class IncrementalTest {
>public static void main(String[] args) {
>int i = 4;
>i = i++;
>System.err.println("i=" + i);
>
>int j = 5;
>int k = 5;
>j = k++;
>System.err.println("j=" + j + "\t\tk=" + k);
>//i=4
>//j=5 k=6
>}
>}
>
>I'm just wondering why does the i++ on the same line as the equals not
>increment it? Does anyone have any ideas? Thanks.
 

{smallsort}

Re:weird incrementor question?

Sultanbek Tezadov wrote:
Quote
1) all values of postfix incrementors are saved
somewhere (say in a "buffer");
2) all postfix incrementors are performed;
3) the entire expression is evaluated with saved values from the "buffer".
However, there's a bigger principle at work here (I wonder if they
discuss this issue in Java classes these days). Read up about "Side
Effects" and "Sequence Points".
Basically,
i = 4;
i = i++; // <= i modified twice between ";"s.
can give you *either* 4 or 5 (depending on the implementation, or even
the phase of the moon; or heck, even 1000000 - the effect is, from the
point of view of the standard, _undefined_). The compiler is free to
reorder the increment and store that is implicit in the "++" with the
store of the left hand side.
The only constraint on the compiler is that both operations must be
complete before the _sequence point_ (in this case, the end of the
statement).
It is illegal for a variable to be modified twice between sequence
points. (In this case, it's not a syntax error, but the effects are
undefined and a program is not well-formed if it does this).
Sequence points are present at:
* statement boundaries (";" or end of block)
* "," operators (but _not_ the "," that separates function call
parameters)
* (Possibly a couple of others that I may have forgotten)..
Other constructs to beware of:
ret = func(i++, i++); // can pass 4,4; 4,5 or 5,4
ret = i++ * i++;
etc.
 

Re:weird incrementor question?

On 7/18/2003 at 10:23:55 AM, Sultanbek Tezadov wrote:
Quote
Here is how it works: 1) all values of postfix incrementors are
saved somewhere (say in a "buffer"); 2) all postfix incrementors
are performed; 3) the entire expression is evaluated with saved
values from the "buffer".
That is not quite right, unless I am misunderstanding your explanation.
According to the JLS (see  15.7) all expressions must be evaluated
(or at least appear to be evaluated) from left to right.
The value of a postfix expression is the value of the variable before
the increment takes place. So if the value if 'i' is 2, the value of
the expression 'i++' is 2, even though it has the side effect of
setting 'i' to 3.
Now take the following example:
int i = 2;
i = i++ * i++;
The evaluation happens as follows:
1) The left side 'i++' is evaluated. Since 'i' is 2, the value of the
sub-expression 'i++' is 2. As a side effect of that evaluation, the
value of i is changed to 3.
2) The right side 'i++' is evaluated. Since 'i' is 3 (as a result of
evaluating the left , the value of the sub-expression 'i++' is 3. As a
side effect of that evaluation, the value of i is changed to 4.
3) The results of the two operands of the '*' operator (2 and 3) are
multiplied, resulting in 6.
4) The result of the expression is assigned to i, so I is now 6.
If I understand what you wrote above, you were saying that the initial
value of 'i' (2) would be saved and used for evaluating the expression,
resulting in 4.
--
Regards,
John McGrath [TeamB]
 

Re:weird incrementor question?

On 7/18/2003 at 3:40:06 PM, Shankar Unni wrote:
Quote
Basically,

i = 4;
i = i++; // <= i modified twice between ";"s.

can give you either 4 or 5
That is true for C/C++, but not for Java. The JLS requires that the
result of the above code is that i == 4;
--
Regards,
John McGrath [TeamB]
 

Re:weird incrementor question?

I'd say try it all to be certain, but I believe that pre and post-fix
operators are performed
before all other operations. So, the example, as explained should be
correct.
Personally, I don't use post-fix operators in that form. Unless I'm
acutally incrimenting
that specific value and only performing that operation, I'll seperate the
process into
seperate lines and be sure that the values I am looking for are acutally
there.
Operations like i = i++; just don't do what I want. In the case of acutally
incrimenting
i, you'd probably want to do i = ++i; // pre-fix operator for that
particular case. But
why do that when i++; should be sufficient?
"Sultanbek Tezadov" < XXXX@XXXXX.COM >wrote in message
Quote
Your explanation is more correct, thanks :-)

--Sultan

On 20 Jul 2003 23:08:13 -0700, John McGrath [TeamB] < XXXX@XXXXX.COM >
wrote:

>On 7/18/2003 at 10:23:55 AM, Sultanbek Tezadov wrote:
>
>>Here is how it works: 1) all values of postfix incrementors are saved
>>somewhere (say in a "buffer"); 2) all postfix incrementors
>>are performed; 3) the entire expression is evaluated with saved
>>values from the "buffer".
>
>That is not quite right, unless I am misunderstanding your explanation.
>According to the JLS (see  15.7) all expressions must be evaluated
>(or at least appear to be evaluated) from left to right.
>
>The value of a postfix expression is the value of the variable before
>the increment takes place. So if the value if 'i' is 2, the value of
>the expression 'i++' is 2, even though it has the side effect of
>setting 'i' to 3.
>
>Now take the following example:
>
>int i = 2;
>i = i++ * i++;
>
>The evaluation happens as follows:
>
>1) The left side 'i++' is evaluated. Since 'i' is 2, the value of the
>sub-expression 'i++' is 2. As a side effect of that evaluation, the
>value of i is changed to 3.
>
>2) The right side 'i++' is evaluated. Since 'i' is 3 (as a result of
>evaluating the left , the value of the sub-expression 'i++' is 3. As a
>side effect of that evaluation, the value of i is changed to 4.
>
>3) The results of the two operands of the '*' operator (2 and 3) are
>multiplied, resulting in 6.
>
>4) The result of the expression is assigned to i, so I is now 6.
>
>If I understand what you wrote above, you were saying that the initial
>value of 'i' (2) would be saved and used for evaluating the expression,
>resulting in 4.
>
 

Re:weird incrementor question?

On 7/21/2003 at 7:31:34 AM, Mark Cogan wrote:
Quote
I'd say try it all to be certain,
To be *really* certain, consult the Java Language Specification (JLS).
Sometimes compilers are wrong, but the JLS is *the* definition of what
is right. But running a test example is sometimes nice to confirm what
you have read in the JLS.
Quote
but I believe that pre and post-fix operators are performed before
all other operations.
As described in the section of the JLS that Sultanbek quoted (?5.7.1),
expressions are evaluated left to right.
Here is an example that will demonstrate it:
int i = 2, j = 2;
System.out.println( "(i + i++) = " + (i + i++) );
System.out.println( "(j++ + j) = " + (j++ + j) );
This will print:
(i + i++) = 4
(j++ + j) = 5
In the first example, the first 'i' is evaluated as 2, then the 'i++'
is evaluated as 2 (with the side effect of setting i to 3). The result
of the expression is 2 + 2 = 4.
In the second example, the first 'i++' is evaluated as 2 (with the side
effect of setting i to 3), then the 'i' is evaluated as 3. The result
of the expression is 2 + 3 = 5.
Quote
Personally, I don't use post-fix operators in that form.
If you did, I think we would have to take you out back and put you out
of your misery. :o)
This sort of "language lawyer" discussion is useful, in that it helps
to gain a good understanding of the language rules. But just as with
the IOCCC, I dearly hope that nobody will take this as an example of
reasonable coding style!
--
Regards,
John McGrath [TeamB]