307

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!

Nayuki
  • 17,911
  • 6
  • 53
  • 80
Michael
  • 3,935
  • 4
  • 24
  • 25

18 Answers18

396
x = x++;

is equivalent to

int tmp = x;
x++;
x = tmp;
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94
  • 47
    Lol, yay for recursive definitions. you probably should've done `x=x+1` instead of `x++` – user606723 Oct 27 '11 at 13:12
  • 8
    @user606723: No. i meant the whole statement `x = x++` , not just the post increment `x++`. – Prince John Wesley Oct 27 '11 at 13:56
  • 25
    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)? – kvb Oct 27 '11 at 17:53
  • 4
    even more clear it is in _asm_ `x=x++` = `MOV x,tmp; INC x; MOV tmp,x` – forker Oct 27 '11 at 19:39
  • 3
    @forker: I think it would be clearer if you used assembly instructions that apply to the processor Michael is using ;) – Carl Oct 27 '11 at 20:30
  • I used `asm` here more as pseudo language. Because explaining the insight of bananas using the same wrapped bananas is quite confusing. :D – forker Oct 27 '11 at 20:53
  • 2
    You should also show the equivalent for `x = ++x` for comparison – endolith Oct 27 '11 at 21:54
  • Yes it is in gcc/clang. But in msvc the final value in increased. – Summer Sun Mar 28 '18 at 12:24
  • @kvb `x++` is a post incement operator, so `something = x++;` is always equivalent to `something = x; x++;`, I guess. – GregT Apr 10 '18 at 12:45
  • This is bad for `?:` operator `howManyHasValue = (Barcode != null) ? howManyHasValue++ : howManyHasValue;` – Evilripper Sep 17 '19 at 09:50
329

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.

Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • 3
    Then, what will you say about x = ++x; – Hisham Muneer May 02 '14 at 16:38
  • 4
    @HishamMuneer `x` gets incremented first before it's read in that case, so you end up with `x + 1`. –  May 03 '14 at 03:01
  • @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. – nantitv Apr 15 '15 at 13:02
  • 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? – Emerald Weapon Apr 24 '16 at 14:35
  • @EmeraldWeapon It's defined in Java. It's only in C/C++ do you see that kind of shenanigans. – Mysticial Apr 24 '16 at 15:08
  • In C this is not defined. See http://c-faq.com/expr/seqpoints.html for more details – emem Sep 17 '18 at 14:47
  • 1
    yet old - but order **is** defined by Java Language Specification. e.g.: [15.7.2. Evaluate Operands before Operation](https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.7.2) – user85421 Aug 02 '19 at 19:32
  • 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. – chirag soni Jan 28 '20 at 16:28
  • 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. – CausingUnderflowsEverywhere Mar 01 '20 at 18:47
263

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 7
    As a side note, OP, you probably mean to just say `x++` instead of `x = x++`. – Jon Newmuis Aug 20 '12 at 07:29
  • 3
    Correct, but maybe emphasize that the increment happens *post* right-hand expression evaluation, but *pre* assignment to left hand side, hence the apparent "overwrite" – Bohemian Aug 20 '12 at 07:31
  • 2
    that seems like one of those high-school programming twisters... good to clear up your basics! – kumarharsh Aug 20 '12 at 10:11
  • +1 I was not sure about the accuracy of your 'translation' and had to test (compile/decompile) it... I found it 100% accurate! ;-) (http://stackoverflow.com/a/12111301/413020) – Alberto Aug 24 '12 at 14:36
  • 1
    @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. – Stephen C Aug 24 '12 at 14:46
  • True, and from the [JLS 15.14.2](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#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. – Alberto Aug 24 '12 at 15:29
  • 1
    @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. – Stephen C Aug 25 '12 at 08:21
  • 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](http://stackoverflow.com/questions/4997513/javac-optimization-flags), [Optimization by Java Compiler](http://stackoverflow.com/questions/5981460/optimization-by-java-compiler). – Alberto Aug 27 '12 at 11:51
  • 4
    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. – Shog9 Sep 06 '12 at 22:43
  • 1
    @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. – Mysticial Sep 06 '12 at 22:46
  • @Shog9 Can you please let me know why my post on this question was deleted? Thanks. (: – Kazekage Gaara Mar 09 '14 at 07:15
  • @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. – Shog9 Mar 09 '14 at 14:31
  • 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? – nathanchere Sep 29 '14 at 14:40
  • 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. – Stephen C Dec 12 '14 at 11:28
  • 1
    *"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++]` – Stephen C Jan 23 '17 at 14:27
  • Or, for that matter, `for (i = 0; i < N; i++) ...` where it doesn't matter if you have a prefix or postfix increment. – Stephen C May 20 '23 at 11:37
32
int x = 7;
x = x++;

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

Community
  • 1
  • 1
user712092
  • 1,988
  • 1
  • 14
  • 16
  • 4
    No it does not depend on the compiler according to the answer you quoted - please edit - -1 for now – Mr_and_Mrs_D Sep 29 '13 at 17:11
  • @Mr_and_Mrs_D Then it depends on what? – Mac Jun 04 '14 at 06:32
  • 2
    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 – Mr_and_Mrs_D Jun 04 '14 at 13:52
16

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.

FMM
  • 4,289
  • 1
  • 25
  • 44
14

According to Byte code obtained from the class files,

Both assignments increment x, but difference is the timing of when the value is pushed onto the stack

In Case1, Push occurs (and then later assigned) before the increment (essentially meaning your increment does nothing)

In Case2, Increment occurs first (making it 8) and then pushed onto the stack(and then assigned to x)

Case 1:

int x=7;
x=x++;

Byte Code:

0  bipush 7     //Push 7 onto  stack
2  istore_1 [x] //Pop  7 and store in x
3  iload_1  [x] //Push 7 onto stack
4  iinc 1 1 [x] //Increment x by 1 (x=8)
7  istore_1 [x] //Pop 7 and store in x
8  return       //x now has 7

Case 2:

int x=7; 
x=++x;

Byte Code

0  bipush 7     //Push 7 onto stack
2  istore_1 [x] //Pop 7 and store in x
3  iinc 1 1 [x] //Increment x by 1 (x=8)
6  iload_1  [x] //Push x onto stack
7  istore_1 [x] //Pop 8 and store in x
8  return       //x now has 8
  • Stack here refers to Operand Stack, local: x index: 1 type: int
Ravi Yenugu
  • 3,895
  • 5
  • 40
  • 58
9

Post Increment operator works as follows:

  1. Store previous value of operand.
  2. Increment the value of the operand.
  3. Return the previous value of the operand.

So the statement

int x = 7;
x = x++; 

would be evaluated as follows:

  1. x is initialized with value 7
  2. post increment operator stores previous value of x i.e. 7 to return.
  3. Increments the x, so now x is 8
  4. Returns the previous value of x i.e. 7 and it is assigned back to x, so x again becomes 7

So x is indeed increased but since x++ is assigning result back to x so value of x is overridden to its previous value.

xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
GauravLuthra
  • 1,027
  • 9
  • 8
8

It's incremented after "x = x++;". It would be 8 if you did "x = ++x;".

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
F.J
  • 243
  • 1
  • 4
7

The incrementing occurs after x is called, so x still equals 7. ++x would equal 8 when x is called

JonPM
  • 129
  • 1
  • 7
7

When you re-assign the value for x it is still 7. Try x = ++x and you will get 8 else do

x++; // don't re-assign, just increment
System.out.println(x); // prints 8
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Vishal
  • 19,879
  • 23
  • 80
  • 93
6

because x++ increments the value AFTER assigning it to the variable. so on and during the execution of this line:

x++;

the varialbe x will still have the original value (7), but using x again on another line, such as

System.out.println(x + "");

will give you 8.

if you want to use an incremented value of x on your assignment statement, use

++x;

This will increment x by 1, THEN assign that value to the variable x.

[Edit] instead of x = x++, it's just x++; the former assigns the original value of x to itself, so it actually does nothing on that line.

josephus
  • 8,284
  • 1
  • 37
  • 57
  • 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. – R. Martinho Fernandes Dec 01 '11 at 02:43
  • if x is originally 7, System.out.println(String.valueOf(x++)); prints 7. you sure we're talking about the same programming language? – josephus Dec 01 '11 at 02:47
  • Yes, I am. This http://www.ideone.com/kj2UU doesn't print 8, like this answer claims. – R. Martinho Fernandes Dec 01 '11 at 02:50
  • 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. – josephus Dec 01 '11 at 03:12
  • 1
    Actually, the increment is the *first thing* that happens. http://www.ideone.com/xOIDU – R. Martinho Fernandes Dec 01 '11 at 03:32
4

What happens when int x = 7; x = x++;?

ans -> x++ means first use value of x for expression and then increase it by 1.
This is what happens in your case. The value of x on RHS is copied to variable x on LHS and then value of x is increased by 1.

Similarly ++x means -> increase the value of x first by one and then use in expression .
So in your case if you do x = ++x ; // where x = 7
you will get value of 8.

For more clarity try to find out how many printf statement will execute the following code

while(i++ <5)   
  printf("%d" , ++i);   // This might clear your concept upto  great extend
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
samprat
  • 2,150
  • 8
  • 39
  • 73
  • 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 – user85421 Aug 02 '19 at 19:53
3

++x is pre-increment -> x is incremented before being used
x++ is post-increment -> x is incremented after being used

int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Roberto Martelloni
  • 587
  • 1
  • 5
  • 17
1

So this means: x++ is not equal to x = x+1

because:

int x = 7; x = x++;
x is 7

int x = 7; x = x = x+1;
x is 8

and now it seems a bit strange:

int x = 7; x = x+=1;
x is 8

very compiler dependent!

linuxeasy
  • 6,269
  • 7
  • 33
  • 40
  • 2
    who said it was equal in first place? – fortran Oct 27 '11 at 13:23
  • @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](http://www.computerhope.com/forum/index.php?topic=82101.0) – linuxeasy Oct 27 '11 at 13:44
  • 1
    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. – fortran Oct 27 '11 at 15:52
  • @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. :) – linuxeasy Oct 27 '11 at 15:57
  • Oversimplifications considered harmful :-p – fortran Oct 27 '11 at 16:18
  • 3
    @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. – Eric Lippert Oct 27 '11 at 17:05
  • @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. – fortran Oct 27 '11 at 17:53
  • 2
    @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! – Eric Lippert Oct 27 '11 at 18:02
  • 1
    *"very compiler dependent"* - Not at all! – Stephen C Jun 25 '17 at 22:43
0

Most simplest explanation!

This is because ++ after the operand makes post increment it, means first the value got assigned to the variable & then incremented. While if you're expecting x value to be 8 then you should pre increment it like the way mentioned below: enter image description here

Shoaib Khalil
  • 1,874
  • 17
  • 10
-1

I think this controversy can be resolved without going into code & just thinking.

Consider i++ & ++i as functions, say Func1 & Func2.

Now i=7;
Func1(i++) returns 7, Func2(++i) returns 8 (everybody knows this). Internally both the functions increment i to 8 , but they return different values.

So i = i++ calls the function Func1. Inside the function i increments to 8, but on completion the function returns 7.

So ultimately 7 gets allocated to i. (So in the end, i = 7)

Pranav Mahajan
  • 2,048
  • 2
  • 23
  • 36
  • 3
    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 ...) – Stephen C May 27 '18 at 11:35
-1

x = x++;

This is the post-increment operator. It should be understood as "Use the operand's value and then increment the operand".

If you want the reverse to happen i.e "Increment the operand and then use the operand's value", you must use the pre-increment operator as shown below.

x = ++x;

This operator first increments the value of x by 1 and then assigns the value back to x.

deepak
  • 375
  • 1
  • 3
  • 8
-2

This is because you used a post-increment operator. In this following line of code

x = x++;

What happens is that, you're assigning the value of x to x. x++ increments x after the value of x is assigned to x. That is how post-increment operators work. They work after a statement has been executed. So in your code, x is returned first after then it is afterwards incremented.

If you did

x = ++x;

The answer would be 8 because you used the pre-increment operator. This increments the value first before returning the value of x.

Anon
  • 59
  • 8