10

My professor recently said that although x = x + 1 and x++ will obviously give the same result, there is a difference in how they are implemented in the JVM. What does it mean? Isn't compiler like: hey, I see x++ so I will switch it to x = x + 1 and carry on?

I doubt there is any difference when it comes to efficiency, but I would be surprised if assembly would be different in those cases...

Mark Thomas
  • 37,131
  • 11
  • 74
  • 101
Eleeist
  • 6,891
  • 10
  • 50
  • 77
  • This will be a duplicate. – Alec Teal Oct 22 '13 at 20:31
  • For clarity, there should be a difference between ++x and x++, but not between x++ and "x = x + 1" or even "x += 1", when used as a stand-alone expression. – drobert Oct 22 '13 at 20:33
  • 4
    This shouldn't be downvoted - it's a perfectly fine question. And @AlecTeal you should present the duplicate if it exists. – sdasdadas Oct 22 '13 at 20:33
  • Increment and decrement operators can be placed before (prefix) or after (postfix) the variable they apply to. If you place an increment or decrement operator before its variable, the operator is applied before the rest of the expression is evaluated. If you place the operator after the variable, the operator is applied after the expression is evaluated. – user20232359723568423357842364 Oct 22 '13 at 20:33
  • 2
    @drobert There is indeed a difference between x++ and x = x + 1. Look it up, it is a duplicate on SO many times... – buzzsawddog Oct 22 '13 at 20:34
  • I love how many people claim it as duplicate without posting a link. – Cruncher Oct 22 '13 at 20:41
  • For my own personal benefit here, it seems that after "int x=0;" the following stand-alone expressions all yield identical byte code: "x += 1" / "x++" / "++x" Makes sense after reading up on 'iinc'. Thanks for the links everybody. – drobert Oct 22 '13 at 20:41
  • @buzzsawddog doesn't talk about `++` in the question, nor the answer. – Cruncher Oct 22 '13 at 20:55
  • Oops, wrong link.... I will see if I can find the link just for you @Cruncher because it seems like your google is broken... – buzzsawddog Oct 22 '13 at 20:56

2 Answers2

29

My professor recently said that although x = x + 1 and x++ will obviously give the same result

I guess your professor perhaps meant - the value of x after x = x + 1 and x++ will be same. Just to re-phrase, as it seems to be creating confusion in interpreting the question.

Well, although the value of x will be same, they are different operators, and use different JVM instructions in bytecode. x + 1 uses iadd instruction, whereas x++ uses iinc instruction. Although this is compiler dependent. A compiler is free to use a different set of instructions for a particular operation. I've checked this against javac compiler.

For eclipse compiler, from one of the comment below from @Holger:

I just tested it with my eclipse and it produced iinc for both expressions. So I found one compiler producing the same instructions

You can check the byte code using javap command. Let's consider the following class:

class Demo {
    public static void main(String[] args) {
        int x = 5;

        x = x + 1;
        System.out.println(x);

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

Compile the above source file, and run the following command:

javap -c Demo

The code will be compiled to the following bytecode (just showing the main method):

 public static void main(java.lang.String[]);
   Code:
      0: iconst_5
      1: istore_1
      2: iload_1
      3: iconst_1
      4: iadd
      5: istore_1
      6: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      9: iload_1
     10: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
     13: iinc          1, 1
     16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
     19: iload_1
     20: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
     23: return
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • 3
    +1 for actually answering the question instead of talking about something completely different that just happens to also involve increment operators ;-) –  Oct 22 '13 at 20:34
  • @Bohemian `x += 1` actually uses the `iinc` instruction only. the 2nd parameter would be `2` for `x += 2`. – Rohit Jain Oct 22 '13 at 20:38
  • The are different! Hence, the bytecode can't be the same, unless in caertain optimiuzed cases. – Ingo Oct 22 '13 at 20:38
  • Naturally, once they've run out of bytecode instructions, they'll have to eliminate one of these. The way Oracle is handling java, they'll probably eliminate `iadd` and change all existing `iadds` to loops of `iinc`. – corsiKa Oct 22 '13 at 20:39
  • I love how a peephole optimiser missed this. – Alec Teal Oct 22 '13 at 20:40
  • @corsiKa I doubt that stage will come. – Rohit Jain Oct 22 '13 at 20:41
  • @corsiKa there is absolutely no way they would drop `iadd` and loop `iinc`. That is completely asinine. Surely they would drop `iinc`, and just use `iadd` to increment... I would rather them increase instruction size increasing the size of all .class files before looping iincs...... – Cruncher Oct 22 '13 at 20:44
  • 1
    @delnan - There may be different compilers. It is not written in stone that a compiler couldn't use iinc for `x = x + 1` under certain circumstances. – Ingo Oct 22 '13 at 20:47
  • @Ingo I guess as far as compilation of Java code to bytecode is concerned, that has to follow JVM instruction set. Compiler can't magically make JVM to use `iinc` for `x = x + 1`. – Rohit Jain Oct 22 '13 at 20:49
  • @Ingo And how does that justify your downvoting this answer? Can you explain what part is not answering the question? – Rohit Jain Oct 22 '13 at 20:51
  • @RohitJain Are you saying `iload x; iinc; dup; istore x` is no valid code for `x = x + 1`? – Ingo Oct 22 '13 at 20:51
  • @Ingo I didn't say that? – Rohit Jain Oct 22 '13 at 20:53
  • @Ingo Well, I guessed it, as it came at the same time you commented. Ignore the comment, if you didn't :) – Rohit Jain Oct 22 '13 at 20:54
  • @RohitJain In the bytecode you listed, instrcutions 3 and 4 can be replaced by `iinc`. There is nothing to prevent **another** compiler from doing it. (Not that it would matter). – Ingo Oct 22 '13 at 20:56
  • @Cruncher I... I don't... I don't even know how to respond if you took my comment seriously in any way whatsoever. – corsiKa Oct 22 '13 at 20:57
  • @Ingo I guess that would be the job of JIT. Yes it can internally convert between `x = x + 1` to use `iinc`, and also `x = x + n` to use `iinc` with `n` as 2nd parameter. But that is not the point. Correct me if I'm going wrong somewhere. – Rohit Jain Oct 22 '13 at 20:57
  • @RohitJain - It's not that you're outright wrong, but you are generalizing an empirical result of a single compilation with a single compiler. And yet, one can reach the conclusion by just **thinking**: the 2 expressions do have different semantics, hence the bytecode **must** be different, **except** maqybe in cases where the expressions are only written for the side effect. But as you demonstrated, there is **at least** 1 compiler that generates different code even in that case. – Ingo Oct 22 '13 at 21:05
  • @Ingo Well, then understand this in deep for different compilers is totally out of my reach ;) I always thought that the compilers implemented for Java should follow JVM instruction. But again you are right in saying, nothing stops a compiler to use a different set of instruction from the available set, to implement the same operation. – Rohit Jain Oct 22 '13 at 21:09
  • @RohitJain Isn't `iinc` a JVM instruction? So I do not understand how the compiler would not "follow JVM instruction". Where is it said that certain expressions **must** be compiled to certain bytecodes? BTW, I read that the Oracle (Sun) compiler deliberately does no optimization, leaving that to the JIT. This explains the different bytecode insofar as the compiler would have to consider the special case that 1 is added. – Ingo Oct 22 '13 at 21:14
  • @Ingo (For first statement)Yes. I said that only. Perhaps improperly framed comment that was. Yes a compiler can use any instruction to represent a certain operation. – Rohit Jain Oct 22 '13 at 21:16
  • 1
    I just tested it with my eclipse and it produced `iinc` for both expressions. So I found one compiler producing the same instructions. – Holger Oct 23 '13 at 07:54
7

The two expressions x++ and x=x+1 will not give the same result, your professor is wrong (or you confused this with ++x, which is again different). To see this

void notthesame() {
    int i = 0;
    System.out.println(i = i + 1);
    i = 0;
    System.out.println(i++);
    System.out.println("See?");
}

Hence, the question for bytecode is meaningless, because 2 different computations can't have the same bytecode.

Ingo
  • 36,037
  • 5
  • 53
  • 100
  • 2
    People, you can downvote me 100 times, it's still *not the same*, hence bytecode doesn't even matter. @sdasdadas Yes, the bytecode is different, at least in this case. – Ingo Oct 22 '13 at 20:36
  • 1
    The bytecode is different even when it's used so that the semantics are the same (read: in a statement on its own). That would be a reasonable unstated assumption. It's fine to point out that they have different semantics in general, but that alone does not answer the question. –  Oct 22 '13 at 20:38
  • 2
    @buzzsawddog I did! How can 2 computations with different result have the same bytecode? It's impossible. Hence. – Ingo Oct 22 '13 at 20:40
  • Based on your new edit, can you explain how ++x is semantically different from `i = i + 1`? – Cruncher Oct 22 '13 at 20:45
  • @Cruncher I could and I would if I didn't get already so many downvotes because alledgedly not answering the question. – Ingo Oct 22 '13 at 20:49
  • @Ingo Of course those two statements are not the same. You are proving it by the fact that `x = x + 1` is a statement, while `x++` is an expression. I guess OP is just concerned about the changes on the value of `x` after those operation, and not based on the context they can be used in. – Rohit Jain Oct 22 '13 at 20:52
  • @RohitJain Unfortunately, assignment *is* an expression in Java. I agree with the rest of your rationale though. –  Oct 22 '13 at 20:56