i = i++

A question was recently posted on the CJUG forum with regards to the following code:

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

The poster wanted to know why in Java the result was 1 whereas in C / C++ the result was 2.

If you’re like me, the first thing that popped in your head was: This person does not have a clear understanding of the postfix increment operator does. Let’s tell him to go suck an egg and get a clue. But then I remembered back to the days when I didn’t know what I was doing either and all of the kind and gentle people on usenet that steered me onto the path of knowledge.

In case you’re having trouble getting over that hurdle, you can look at the problem as follows:

int[] a = { 0, 1, 2 };
int i;
i = 1;
a[i] = i++;
System.out.println("a[0]=" + a[0] + ", a[1]=" + a[1] + ", a[2]=" + a[2]);

which is slightly more palatable and results in the following:

a[0]=0, a[1]=1, a[2]=2

I’ll spare the long winded answer to the reason why Java returns what it does and refer you to a Java forum posting. (Though if you want me to ramble on about it, just ask!) That takes care of the Java part, but what about C / C++? Well, if you didn’t get all soft and squishy developing in Java all these years, you’ll remember that the order of evaluation of operands of individual operators and the order in which side effects take place is unspecified in C / C++. You’ll also start remembering about sequence points and all of that but before you begin to spasm uncontrollably, you’ll remember that you’ve left all that behind you now. At the end of the day, the fact that the particular C / C++ compiler, runtime, etc resulted in 2 is simply luck of the draw. The expression is undefined. To quote Dale King:

…in C that statment might assign 0, 1, 42, -1 or any other value to i. It might crash your machine, erase your hard drive, or cause your computer to melt down. All would be acceptable results of
executing that statement, since its behavior is undefined.

There is also Steve Summit’s famous response which provides links to the C FAQ for more information.

Advertisements

11 comments

  1. “This person does not have a clear understanding of the postfix increment operator does. Let’s tell him to go suck an egg and get a clue.”
    That’s a rather foolish comment, since the question was about a difference in the results of the postfix increment operator across languages; a question about such a difference is quite independent of any knowledge of the operator at hand. The a[i] example you gave is irrelevant and misses the point, which concerns the value of the variable i after the statement is executed, not the value of i++, which is of course by definition the same as the value of i before the statement was executed. And the blog entry is as completely clueless as your own comments.
    The issue here is not the obvious fact, probably well-known to the person that asked the question, that the value of i++ is the value of i before the increment, but rather the not at all obvious value of the variable i after the statement i = i++ is executed. That value depends on whether the increment of i occurs before or after the assignment. Which has nothing to do with the an understanding of the postfix operator, clear or not; the only way to know that is to read the JLS, which stipulates that the increment occurs first, thus i is left with the value of 1, not 2 … but Gosling could just as well have specified it the other way around. As for C, that’s the only thing you get right … that it’s unspecified. In some implementations the value will be 1, in some it will be 2, and in some it will be one or the other based on optimization flags. Nowhere, though, will it be anything else, as a practical matter of compiler design. As a former member of X3J11, the ANSI C standards committee, I can tell you that the widely seen comment about erasing your hard drive, which was oft used by committee members and certainly did not originate with Dale King, is a bit of a silly in-joke. Since the standard doesn’t specify the behavior, then from *it’s* point of view, the implementation could erase your disk drive … *without being in violation of the standard*. But saying that that would be an “acceptable result” is plain stupid, a point that the standard makes oblique reference to via the phrase “quality of implementation”.

  2. Here’s another point to further illustrate what’s at issue. What’s the value of i after i = 1; i = ++i; in C? This is *also* undefined, and in some implementations i might be 3, especially if i+1 had been calculated previously and is still in a live register. Why? Because i = ++i can be decomposed into RHS = i+1, LHS = RHS, and ++i, and the standard doesn’t specify their order.
    The C standard committee was largely made up of compiler vendors, whose marketing depends heavily on performance evaluation (aka benchmark cooking), and so the language definition goes out of its way not to invalidate optimizations. Java, OTOH, had a very different goal, of producing the same results in all implementations, so it nailed down everything, from the size of an integer to the order of evaluation to the (very bad) hash function for the String class. *That* is the answer to the question, not some juvenile strawman about not understanding the post-increment operator.

  3. As another illustration of how off-base your comments and example are, consider the effect of each of the following in Java. Don’t cheat; decide what they do *before* testing it in the compiler.
    a[i++] = i;
    a[i++] = i++;
    a[i++] = ++i;

  4. WoW! Someone clearly woke up on the wrong side of the bed this morning and decided to use that fact to blast into me. While I certainly appreciate your insight into what initially appears to be a trivial problem, your other comments are simply out of place and had no reason to be posted.
    My two statements: “If you’re like me, the first thing that popped in your head was: This person does not have a clear understanding of the postfix increment operator does. Let’s tell him to go suck an egg and get a clue. But then I remembered back to the days when I didn’t know what I was doing either and all of the kind and gentle people on usenet that steered me onto the path of knowledge” are *clearly* a subtle attempt at humor. Why? Because anyone that has spent any time reading usenet posts knows that people are anything but “kind and gentle”. In most cases all you get is a verbal lashing as to how ignorant and foolish you are (quite similar to your comments posted here though I am by no means saying that you are as brash as most usenet postings).
    I will not bother to defend or clarify any of my other statements since you have obviously taken them in a manner that differs from the way that they were intended. I will only say that I apologize if they in any way offended you as that was not the intent.
    Again, I certainly appreciate your insight into this interesting and non-trivial problem.

  5. TS was right in everything he posted… why did you felt offended? If know to little about something than don’t try to answer just to brag you know something… You will only make things unclearer.
    PS. You did not answer the question at all

  6. Hello Sil! Thanks for the comment.
    If you can tell me in what way you don’t think that I answered the question, I will be more than happy to elaborate for you.

  7. I wondered too,why my PC crashes when I use i=i++; in a while loop to increment the counter although i=++i; works.
    I found that i=i++; is the same as i=i; which does not make any sense to me.
    I suggest to log this as a bug !#~

  8. to :Ralf Steffler
    post increment really means increment the value after it’s next use, that’s to say , the value of i++ equals i ,but when we use i next time , i is increase by 1 .
    OK .Let’s see your examples ;
    +++++++++++++++++++++++++++++++
    int k= 1;
    k= k++ + k;
    +++++++++++++++++++++++++++++++
    In the code above , let’s evaluate from right first.
    k++ = 1 because it equals to k .
    the second k , is treated as the second time use of k ,and increase by 1 ,and k now is 2 .
    1 + 2 assigns to new k ,new k is 3 .
    ++++++++++++++++++++++++++++++
    k = k + k++ ;
    ++++++++++++++++++++++++++++++
    In this code , again see the right first.
    k is 1 ,and k++ is the value of k , also equals 1 , 1+1 = 2.
    That’s the answer.
    Last week ,I went to a very important interview ,I prepare this interview for several days ,but they give me a paper full of stupid questions , most questions related to ++ , –. F**k it, I mess up that interview test. The people ask this kind of question always think they are clever and you may be not clever as they are , they’re evil .This has little to do with knowledge .


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s