Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

Question about ++

Thread view: 
richnjones@gmail.com - 09 Apr 2007 16:36 GMT
Hello all,

I have got a question about the post increment operator. Consider the
following code

int i = 1;
System.out.println(i);
i = i++;
System.out.println(i);

The output is
1
1

I expect the first 1 because I am (for sanities sake) outputting the
value of i before any operations are done on it.

I then expect the value of i on the right of the = to be assigned to
the i on the left of the equals. I expect that to copy it and then the
increment to happen. I do not see why the increment is not done on teh
i to the left of the equals. I know this is with primitives whcih pass
by value but I was expected an output of
1
2

It seems int he code above the ++ is completly disregarded

What made me think of this is another question in the forum

(http://groups.google.co.uk/group/comp.lang.java.programmer/
browse_thread/thread/
fb0d3fbd12040ba3/5153c4175a471b0a#5153c4175a471b0a)

asking the answer to

 int a = 1;
 int b = a++ + a++;
 System.out.println("A = " +  a);
 System.out.println("B = " +  b);

in C. I tried it in Java and the b=.... line seemed to be doing
operations left to right although Im not too clear with this either

The output is

A = 3
B = 3

Can anyone clarify what is expected when ++ and assigning

Thanks
Daniel Pitts - 09 Apr 2007 16:54 GMT
On Apr 9, 8:36 am, richnjo...@gmail.com wrote:
> Hello all,
>
[quoted text clipped - 47 lines]
>
> Thanks

try this simple example:
class Increments {
 public static void main(String[] args) {
   int a = 0;
   int b = 0;
   System.out.println(a++);
   System.out.println(a);
   System.out.println(++b);
   System.out.println(b);
 }
}

The output would be:
0
1
1
1
...
a++ is called the "Post increment operator", meaning that after the
current statement completes, a will be incremented.  "++a" is the "pre
increment operator" meaning that a will be incremented, and its new
value used.

In either case, you should never use "x = x++", just use "x++" or "+
+x".

x = x++ is similar to "int _tmp = x; x = x + 1; x = _tmp"
Yuck.
Patricia Shanahan - 09 Apr 2007 18:47 GMT
...
> a++ is called the "Post increment operator", meaning that after the
> current statement completes, a will be incremented.  "++a" is the "pre
> increment operator" meaning that a will be incremented, and its new

The "after the current statement" model works for some cases, but fails
to explain why

public class YuckyTest {
  public static void main(String[] args) {
    int a = 1;
    int b = a++ + a++;
    System.out.println(b);
  }
}

prints 3, not 2.

In the JLS they are called "postfix increment operator" and "prefix
increment operator", making the "post" or "pre" refer to the syntax, not
the functionality.

Patricia
Luc The Perverse - 09 Apr 2007 22:13 GMT
> The "after the current statement" model works for some cases, but fails
> to explain why
[quoted text clipped - 6 lines]
>   }
> }

If I saw that I think I'd have to slap whoever wrote it!

Well . . unless it was a NG example.

--
LTP

:)
Patricia Shanahan - 09 Apr 2007 17:06 GMT
> Hello all,
>
[quoted text clipped - 22 lines]
>
> It seems int he code above the ++ is completly disregarded

If you really want to understand code like "i=i++;", you need to
understand the definition of postfix ++ in Java,
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.15.1

There are a couple of significant aspects to every operation:

1. What result, if any, does it provide for use in subsequent calculations?

2. What side effects does it have?

For postfix ++, the result is the old value of the variable, and the
side effect is to increment the variable by 1.

Java completely evaluates the right hand side of an assignment before
performing the assignment. The sequence for i=i++; with i initially 1 is:

Determine the left hand side field - trivial because it is not an array
access or anything else that might have side effects.

Evaluate the right hand side
  Calculate the result, 1
  Perform the side effect, change i to 2

Do the assignment, setting i to the right hand side result, 1.

Of course, a smart optimizer might decide all this is a waste of time,
and do nothing, but the results will be the same as though this was all
done.

> What made me think of this is another question in the forum
>
[quoted text clipped - 16 lines]
> A = 3
> B = 3

Evaluate the right hand side
  Evaluate the left operand of the binary +
    Result is old value of a, 1
    Side effect, change a to 2
  Evaluate the right hand side of the +
    Result is old value of a, 2
    Side effect, change a to 3
  Evaluate the binary +
    Result is sum of the left and right hand side results, 3
Do the assignment, setting b to the right hand side result, 3

> Can anyone clarify what is expected when ++ and assigning

My usual expectation when code combines ++ and assigning is very
confused, unreadable code that probably does not do what the programmer
intended. Even if done "correctly" in the sense of getting the intended
result, it is a warning sign of code that sacrifices clarity in favor of
unnecessary cleverness.

Patricia
richnjones@gmail.com - 09 Apr 2007 17:36 GMT
> richnjo...@gmail.com wrote:
> > Hello all,
[quoted text clipped - 97 lines]
>
> - Show quoted text -

Thanks for the replies.
I would never use code like i=i++; but was curious to see what
happened. I'll look at the link you posted Patricia and if I have any
other questions I'll come back to you
Thanks again
Luc The Perverse - 09 Apr 2007 17:37 GMT
> I have got a question about the post increment operator. Consider the
> following code
*snip*

Daniel and Patricia offered excellent explanations about what is going on.

One thing that is important to note is that the statement

i=i++;

really doesn't make any sense.  In Java, it can never change the value of i,
no matter the data type of i.  It's typically just something that teachers
put on tests and assignments to see if people are paying attention or
understanding the underlying concepts.

If you were trying to increment i then just use

i++

If you wanted to increment i and save a copy of the old value, it would be
more clear to write.

int oldI = i;
i++;

But you ~could~ compress those into one line like this

int oldI = i++;

Though I can't really think of a practical reason that you would want to do
that

--
LTP

:)
Lew - 10 Apr 2007 14:54 GMT
> int oldI = i++;
>
> Though I can't really think of a practical reason that you would want to do
> that

Lookahead algorithms.  Sometimes it's convenient to know both i and i+1
without having to repeat the addition all the time.

In any case an idiom like this would be part of a very local block.

Signature

Lew

Patricia Shanahan - 10 Apr 2007 15:51 GMT
>> int oldI = i++;
>>
[quoted text clipped - 5 lines]
>
> In any case an idiom like this would be part of a very local block.

But why not code it as

int oldI = i;
i++;

which completely avoids multiple side effects in one statement?

Patricia
Luc The Perverse - 10 Apr 2007 17:53 GMT
> But why not code it as
>
> int oldI = i;
> i++;
>
> which completely avoids multiple side effects in one statement?

What!

Have you never heard of "obfuscation" ?

--
LTP

:)
Tor Iver Wilhelmsen - 13 Apr 2007 19:40 GMT
På Mon, 09 Apr 2007 18:37:31 +0200, skrev Luc The Perverse  
<sll_noSpamlicious_z_XXX_m@cc.usu.edu>:

> i=i++;
>
> really doesn't make any sense.

Well, it can be useful in C/C++ which don't define the consequence of that  
statement. :)

int main(int argc, char** argv) {
  int i = 1;
  i = i++;
  if (i != 1) {
    printf("I disagre with what the compiler has done with me and will  
terminate.\n");
    printf("Plese recompile me with a compiler that is not like totally  
WRONG.\n");
    exit(0);
  }
  else {
    /* Do something useful */
  }
}
angrybaldguy@gmail.com - 14 Apr 2007 06:21 GMT
On Apr 13, 11:41 am, "Tor Iver Wilhelmsen" <tori...@operamail.com>
wrote:

> Well, it can be useful in C/C++ which don't define the consequence of that
> statement. :)
...
>    int i = 1;
>    i = i++;
[quoted text clipped - 5 lines]
>      exit(0);
>    }

You can do that, but it's still wrong.  In C++ with primitive types
the statement
 i = i++;
is free to leave i == 1 but also format your hard drive, or corrupt
some random piece of the stack, or invite your in-laws over to stay
with you.  More practically, the above code is likely to be VERY
sensitive to optimization settings and may well trigger even when the
program's logic would otherwise run fine.

In short, Don't Do That.
ruds - 11 Apr 2007 05:34 GMT
On Apr 9, 8:36 pm, richnjo...@gmail.com wrote:
> Hello all,
>
[quoted text clipped - 47 lines]
>
> Thanks

You are using the post increment operator ++,so when u r writing
i=i++;
the actual value  of i is first asigned and then i is incremented.
so first assignment takes place and then increment.
Chris Smith - 24 Apr 2007 04:24 GMT
> > int i = 1;
> > System.out.println(i);
[quoted text clipped - 4 lines]
> > 1
> > 1

> You are using the post increment operator ++,so when u r writing
> i=i++;
> the actual value  of i is first asigned and then i is incremented.
> so first assignment takes place and then increment.

That is not true.  Obviously, if it were true, then the given output
would be different.  If the assignment happened first (setting i to 1)
and then the increment (setting i to 2), then the second line of output
would read "2".  It doesn't, so that execution model is wrong.  I don't
know who it was that first described the behavior of post-increment in
terms of when the increment happens.  Whoever first spread that
misunderstanding about Java should be ashamed of themselves.

What really happens is that the expression is evaluated whenever the
evaluator gets to it.  Nothing is delayed or put off.  The evaluation
has a side-effect (incrementing the variable) and a result (the value of
the variable before the increment).  Both the side effect and the
evaluation itself are fully performed at that point.  Then the execution
goes on to process other subexpressions.

So you start out with the following:

          =
         / \
        i  post-++
             \
              i

First, the left hand side of the assignment is evaluated, obtaining the
location of the variable i.  Let's say it's memory address 123, which
I'll write as M[123].  There is no side-effect.  So,

          =
         / \
   M[123]  post-++
             \
              i

Next, the right-hand side of the assignment is evaluated.  The right-
hand side of the assignment is a post-increment, so the first step is to
evaluate the variable to an lvalue.  It's the same variable, so:

          =
         / \
   M[123]  post-++
             \
             M[123]

Now that the operand to the post-increment has been evaluated, the post-
increment itself is evaluated.  This has two effects.  It reads the
value of M[123], and gets 1.  That is the result of the expression.  
Also, right now (NOT delayed) it increments the value in that memory
location as a side-effect.  It does not increment the result of the
expression; that's still 1.

          =
         / \
   M[123]   1

   (as a side effect, now M[123] == 2)

Finally, the '=' operator has had both of its operands evaluated, so the
operator itself gets evaluated.  This again does two things.  First of
all, the result of the expression is the same as the right-hand side,
which is 1.  Second, the value of the RHS is stored into the memory
location described by the LHS as a side effect.  So,

          1

   (as a side effect, now M[123] == 1)

So as you can see, the value of i did briefly get assigned to 2, but was
then overwritten by 1 again, explaining the fact that nothing appears to
have changed.  The order of those two writes to i -- the post-increment,
and then the assignment -- is critical to understanding what happens
here, and it's certainly wrong to say that the increment happens at some
later time.  As you can plainly see, the increment happened in exactly
the same evaluation step as when the value of that subexpression was
decided.  It wasn't delayed in the slightest.

(As a side note, none of this applies to C or C++, despite the fact that
they have operators that look identical.  Both of those languages allow
considerably greater flexibility to their implementations in terms of
the result of expressions like this.  We're just talking Java here.)

Signature

Chris Smith



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.