What is x after "x = x++"?

48,528

Solution 1

x does get incremented. But you are assigning the old value of x back into itself.


x = x++;
  1. x++ increments x and returns its old value.
  2. x = assigns the old value back to itself.

So in the end, x gets assigned back to its initial value.

Solution 2

x = x++;

is equivalent to

int tmp = x;
x++;
x = tmp;

Solution 3

The statement:

x = x++;

is equivalent to:

tmp = x;   // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
           //     happens after the value is captured.
x = tmp;   // ... this is the effect of assignment operation which is
           //     (unfortunately) clobbering the incremented value.

In short, the statement has no effect.

The key points:

  • The value of a Postfix increment/decrement expression is the value of the operand before the increment/decrement takes place. (In the case of a Prefix form, the value is the value of the operand after the operation,)

  • the RHS of an assignment expression is completely evaluated (including any increments, decrements and/or other side-effects) before the value is assigned to the LHS.

Note that unlike C and C++, the order of evaluation of an expression in Java is totally specified and there is no room for platform-specific variation. Compilers are only allowed to reorder the operations if this does not change the result of executing the code from the perspective of the current thread. In this case, a compiler would be permitted to optimize away the entire statement because it can be proved that it is a no-op.


In case it is not already obvious:

  • "x = x++;" is almost certainly a mistake in any program.
  • The OP (for the original question!) probably meant "x++;" rather than "x = x++;".
  • Statements that combine auto inc/decrement and assignment on the same variable are hard to understand, and therefore should be avoided irrespective of their correctness. There is simply no need to write code like that.

Hopefully, code checkers like FindBugs and PMD will flag code like this as suspicious.

Solution 4

int x = 7;
x = x++;

It has undefined behaviour in C and for Java see this answer. It depends on compiler what happens.

Solution 5

A construct like x = x++; indicates you're probably misunderstanding what the ++ operator does:

// original code
int x = 7;
x = x++;

Let's rewrite this to do the same thing, based on removing the ++ operator:

// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7

Now, let's rewrite it to do (what I think) you wanted:

// original code
int x = 7;
x++;

The subtlety here is that the ++ operator modifies the variable x, unlike an expression such as x + x, which would evaluate to an int value but leave the variable x itself unchanged. Consider a construct like the venerable for loop:

for(int i = 0; i < 10; i++)
{
    System.out.println(i);
}

Notice the i++ in there? It's the same operator. We could rewrite this for loop like this and it would behave the same:

for(int i = 0; i < 10; i = i + 1)
{
    System.out.println(i);
}

I also recommend against using the ++ operator in larger expressions in most cases. Because of the subtlety of when it modifies the original variable in pre- versus post-increment (++x and x++, respectively), it is very easy to introduce subtle bugs that are difficult to track down.

Share:
48,528

Related videos on Youtube

Michael
Author by

Michael

Updated on March 07, 2021

Comments

  • Michael
    Michael about 3 years

    What happens (behind the curtains) when this is executed?

    int x = 7;
    x = x++;
    

    That is, when a variable is post incremented and assigned to itself in one statement? I compiled and executed this. x is still 7 even after the entire statement. In my book, it says that x is incremented!

    • stivlo
      stivlo over 12 years
      Try this: int x = 7; x = ++x;, of course is still horrible code, you don't need to reassign. int x = 7; x++; is enough.
    • Yousf
      Yousf over 12 years
      This is a really bad practice, don't increment variable in the same line you use it.
    • Lemon
      Lemon over 12 years
      I'd prefer to use x += 1, except maybe in loops. for(int x=0; x<7; x++)
    • andyortlieb
      andyortlieb over 12 years
      Is the reference to the object x in "x++" just getting thrown away if since the old x value is being re-assigned to the new x value before the old x is post-incremented?
    • fortran
      fortran over 12 years
      @andyortlieb there is no object, just a basic value.
    • Hammad Khan
      Hammad Khan over 12 years
      This actually is not duplicate! ++x and x++ is a whole different than what this question is about? Why do they close all good questions?
    • Chris Burt-Brown
      Chris Burt-Brown over 11 years
    • Dawood ibn Kareem
      Dawood ibn Kareem over 11 years
      Don't write y=y++; or anything similar. Doing the ++ part (whether you write it before or after the variable) automatically does the assignment for you.
    • Sephallia
      Sephallia over 11 years
  • user606723
    user606723 over 12 years
    Lol, yay for recursive definitions. you probably should've done x=x+1 instead of x++
  • fortran
    fortran over 12 years
    who said it was equal in first place?
  • linuxeasy
    linuxeasy over 12 years
    @fortran Well at several places we have read it, and even in starter books, the meaning is explained this way that: x++ means x=x+1. You can consider the following link for the same as one of the many answers explanation_link
  • Prince John Wesley
    Prince John Wesley over 12 years
    @user606723: No. i meant the whole statement x = x++ , not just the post increment x++.
  • fortran
    fortran over 12 years
    If I were you I'd trash these books immediately xD In any case, it would be like (x = x + 1, x-1) in C, where comma separated expressions are allowed.
  • linuxeasy
    linuxeasy over 12 years
    @fortran yes I agree now. but I guess they are for explanation purpose, guess how tough it would be for a starter to try to understand what exactly x++ means. :)
  • fortran
    fortran over 12 years
    Oversimplifications considered harmful :-p
  • Eric Lippert
    Eric Lippert over 12 years
    @fortran: Well, in my decade-old copy of "The Java Programming Language, Third Edition" on page 159 it says ""The expression i++ is equivalent to i=i+1 except that i is evaluated only once". Who said it in the first place? James Gosling, it would appear. This portion of this edition of the Java spec is extraordinarily vague and poorly specified; I presume that later editions cleaned up the language to express the actual operator semantics more clearly.
  • kvb
    kvb over 12 years
    I don't think this is all that useful without further explanation. For instance, it's not true that x = ++x; is also equivalent to int tmp = x; ++x; x = tmp;, so by what logic can we deduce that your answer is correct (which it is)?
  • fortran
    fortran over 12 years
    @EricLippert even after writing it, you seem glad to ignore except that i is evaluated only once; and that is not even true for i++, but for ++i. I don't have a copy handy, but I doubt that such a gross mistake is made in that book.
  • Eric Lippert
    Eric Lippert over 12 years
    @fortran: by "except i is evaluated only once" the standard is attempting to convey that an expression like "M().x++" only calls M() once. A less vague and more accurate wording would emphasize that there is a difference between evaluating i as a variable to determine its storage location -- which is what is meant by "evaluated only once" here -- and reading or writing to that storage location -- either of which could be a reasonable but incorrect interpretation of 'evaluated'. Clearly the storage location has to be both read and written!
  • forker
    forker over 12 years
    even more clear it is in asm x=x++ = MOV x,tmp; INC x; MOV tmp,x
  • Carl
    Carl over 12 years
    @forker: I think it would be clearer if you used assembly instructions that apply to the processor Michael is using ;)
  • forker
    forker over 12 years
    I used asm here more as pseudo language. Because explaining the insight of bananas using the same wrapped bananas is quite confusing. :D
  • endolith
    endolith over 12 years
    You should also show the equivalent for x = ++x for comparison
  • R. Martinho Fernandes
    R. Martinho Fernandes over 12 years
    If it is incremented after x = x++, then it should be 8.
  • R. Martinho Fernandes
    R. Martinho Fernandes over 12 years
    The one that says it increments after assigning, and the one that says it will print 8. It increments before assigning, and it prints 7.
  • josephus
    josephus over 12 years
    if x is originally 7, System.out.println(String.valueOf(x++)); prints 7. you sure we're talking about the same programming language?
  • R. Martinho Fernandes
    R. Martinho Fernandes over 12 years
    Yes, I am. This ideone.com/kj2UU doesn't print 8, like this answer claims.
  • josephus
    josephus over 12 years
    yes, i was wrong. x = x++ will assign 7 to x first before incrementing x. as x++ (which is an assignment in itself) resolves first before x = (whatever), the value assigned to x in x=(whatever) will follow. sorry i didn't see that.
  • R. Martinho Fernandes
    R. Martinho Fernandes over 12 years
    Actually, the increment is the first thing that happens. ideone.com/xOIDU
  • Jon Newmuis
    Jon Newmuis over 11 years
    As a side note, OP, you probably mean to just say x++ instead of x = x++.
  • Bohemian
    Bohemian over 11 years
    Correct, but maybe emphasize that the increment happens post right-hand expression evaluation, but pre assignment to left hand side, hence the apparent "overwrite"
  • kumarharsh
    kumarharsh over 11 years
    that seems like one of those high-school programming twisters... good to clear up your basics!
  • FMM
    FMM over 11 years
    I must emphasize that this answer - while it is the best answer available so far (and I upvoted as such) - fails to admonish towards a construct like x = x++; most certainly being a misunderstanding of the concepts.
  • Alberto
    Alberto over 11 years
    +1 I was not sure about the accuracy of your 'translation' and had to test (compile/decompile) it... I found it 100% accurate! ;-) (stackoverflow.com/a/12111301/413020)
  • Stephen C
    Stephen C over 11 years
    @Alberto - It is good to hear that you don't take "expert" statements as "gospel truth". However, a better way to validate what I said would be to consult the JLS. Your compile / decompile test only shows that what I said is valid for one Java compiler. Others could (hypothetically) behave differently ... except that the JLS doesn't allow that.
  • Alberto
    Alberto over 11 years
    True, and from the JLS 15.14.2 there is no much room for other postfix-increment-operator implementations, but to be fair, I was expecting some kind of optimization by default, for example not calculating y + 1.
  • Stephen C
    Stephen C over 11 years
    @Alberto - bytecodes are minimally optimized. The significant optimizations are all done by the JIT compiler. OTOH, this may be a situation which doesn't get optimized. The statement is really an obscure way of doing nothing, and is unlikely to occur in production code. A specific optimization for this case would a waste of effort, and a waste of JIT compiler time.
  • Alberto
    Alberto over 11 years
    Thanks for opening my eyes :-) After more testing: int x = 1; x = 1; I found that not Sun's javac 1.6.0_33 nor OpenJDK javac 1.7.0_05 javac's do optimize at all: iconst_1, istore_1, iconst_1, istore_1. Afterwards, I could confirm this also in SO: javac optimization flags, Optimization by Java Compiler.
  • Shog9
    Shog9 over 11 years
    Just a FYI: this was originally posted to a different question, which was closed as a duplicate of this one and has now been merged.
  • Mysticial
    Mysticial over 11 years
    @StephenC I found this answer deleted with the question. It bothered me enough to ping a mod to move it here where it is arguably the best answer.
  • Mr_and_Mrs_D
    Mr_and_Mrs_D over 10 years
    No it does not depend on the compiler according to the answer you quoted - please edit - -1 for now
  • Kazekage Gaara
    Kazekage Gaara about 10 years
    @Shog9 Can you please let me know why my post on this question was deleted? Thanks. (:
  • Shog9
    Shog9 about 10 years
    @Kazekage: there's a complicated bit of history there. I merged a bunch of these answers in from another deleted question, which was similar but not similar enough to where all of them could answer this question. Some of them (like this one) were easy enough to edit, most were not. Given they were already deleted when I found them, I figured it was more important to save a few than leave all lost.
  • Hisham Muneer
    Hisham Muneer almost 10 years
    Then, what will you say about x = ++x;
  • Admin
    Admin almost 10 years
    @HishamMuneer x gets incremented first before it's read in that case, so you end up with x + 1.
  • Mac
    Mac almost 10 years
    @Mr_and_Mrs_D Then it depends on what?
  • Mr_and_Mrs_D
    Mr_and_Mrs_D almost 10 years
    It's undefined behavior_only for C_. Even so saying it depends on the compiler is misleading - it implies the compiler should kind of specify this behavior. I revert my vote but consider editing your answer - edit: oops I can't - you have to edit it first :D
  • nathanchere
    nathanchere over 9 years
    My reasoning is obviously wrong but I would have expected the resolution to be that x is assigned the value of itself, then once the statement is resolved x is incremented. Otherwise what's the point of having the postfix operator?
  • Stephen C
    Stephen C over 9 years
    The postfix operator is not intended to be used like this. See the last part of my answer. Unfortunately, it is not practical to design a programming language that will protect the naive programmer from all possible mistakes.
  • nantitv
    nantitv about 9 years
    @HishamMuneer It's too late. But I am putting it here because it may be helpful for some other people who will look in future. The best way to under stand this problem is looking at the assembly code created for x=x++ and x=++x. Please see the answer of Thinkingcap also.
  • Emerald Weapon
    Emerald Weapon about 8 years
    I know this is super old, but I have a question. Is the above order of operation guaranteed by the standard? Is it possible that the assignment is executed before the increment?
  • Mysticial
    Mysticial about 8 years
    @EmeraldWeapon It's defined in Java. It's only in C/C++ do you see that kind of shenanigans.
  • Nihar
    Nihar over 7 years
    Can you please explain your answer in details .
  • Stephen C
    Stephen C over 7 years
    "Otherwise what's the point of having the postfix operator?" ... It is to do the many useful / correct things that you can do with postfix; e.g. x[i++]
  • Ravi Yenugu
    Ravi Yenugu over 7 years
    Pls take a look at the referenced link and comments
  • Stephen C
    Stephen C almost 7 years
    "very compiler dependent" - Not at all!
  • Summer Sun
    Summer Sun about 6 years
    Yes it is in gcc/clang. But in msvc the final value in increased.
  • Summer Sun
    Summer Sun about 6 years
    But in msvc x is 8. Yes in gcc and clang x is 7.
  • GregT
    GregT about 6 years
    @kvb x++ is a post incement operator, so something = x++; is always equivalent to something = x; x++;, I guess.
  • Stephen C
    Stephen C almost 6 years
    There is no valid "controversy" here. The code demonstrably behaves in a particular way, and the behavior conforms to the JLS. Anyone who thinks it behaves differently either hasn't tried it, or they are deluded. (This is a bit like saying that 7 x 7 is 49 is "controversial" when someone has forgets their times tables ...)
  • emem
    emem over 5 years
    In C this is not defined. See c-faq.com/expr/seqpoints.html for more details
  • user85421
    user85421 over 4 years
    yet old - but order is defined by Java Language Specification. e.g.: 15.7.2. Evaluate Operands before Operation
  • user85421
    user85421 over 4 years
    not correct " The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1" - this would make x being 8, but it is 7 - increment happens between reading and assignment
  • Evilripper
    Evilripper over 4 years
    This is bad for ?: operator howManyHasValue = (Barcode != null) ? howManyHasValue++ : howManyHasValue;
  • chirag soni
    chirag soni about 4 years
    anybody trying to understand x=x++ keep in mind that post-increment has given priority over the assignment and x++ increments but returns old value.
  • CausingUnderflowsEverywhere
    CausingUnderflowsEverywhere about 4 years
    Actually, a bit contrary to how it's described in 1. , the value of x is first retrieved and inserted into the expression, and then x is incremented. Finally as 2. describes the retrieved value i assigned to x, overwriting the incremented x. 1. 's description should be reversed to outline that x is returned first then incremented.