2

@bibiki: What I care is to learn how this actually works

Quite right. Here's how it is defined to work by the JLS:

Java Language Spec 15.14 (postfix Operators)

... the value 1 is added to the value of the variable and the sum is stored back into the variable ... The value of the postfix increment expression is the value of the variable before the new value is stored.

so yes, there is a "new block in memory", but it's used to hold the value of the expression, ie the evaluation of the postfix ++ is like this:
int valueOfExpression = num;
num = num + 1;

and 15.26 (Assignment operators)

the right-hand operand is evaluated ... the result of the conversion is stored into the variable.

so after the expression is evaluated (see above) the value of the expression is stored in the LHS, ie
`num = valueOfExpression;

Edited by JamesCherrill

Votes + Comments
short 'n sweet
-1

Hey JamesCherrill, I still am confused. rather than:

int valueOfExpression = num;
num = num + 1;

I thought, what actually happnes is:

    int num = 0;
    //when we write num = num++;, what I think happens is:
    int valueOfExpression = num;
    num = num;
    valueOfExpression = num + 1;
    //and this leaves num 0, instead of incrementing it to 1.

stultuske, you're right, there is no reason for any emotional reaction on my part for Java's contradiction to my expectations. And, one of the reasons I like being a programmer is that there is no room for arguing with the compiler. But there is nothing wrong with saying Java si wrong either man. Alright, take care.

1

All I can say is "keep going back to the JLS". It states explicitly that the value of the expression is the value before the new value is stored, so your line 5 contradicts the JLS.

ps: If you want to have a "Java is wrong" debate, how about: adding a "protected" keyword to something makes it less protected!

0

hey JamesCherrill, thanks for your patience. I really appreciate it. I understand that part

the value of the expression is the value before the new value is stored,

and am also aware that ++num increments num first, and then does the rest of operations.
Anyways, I'll look at JLS, although I think I got it clearer now.

kind regards.
P.S. Thanks for the protected-less protected topic. I now have something to research about.

1

I do agree with Tokamak that the c++ example he mentioned is closer to how my intuition expects the code to work than Java.

You and Tokamak are certainly not the only people whose intuition goes that way (mostly, I think, because a lot of people mis-explain x++ as "do something with x and then increment x afterwards") and I do agree that some people's reactions here were needlessly arrogant for something that really a lot of people do get wrong. That said it's still wrong and based on a misunderstanding of how x++ works.

If ++ was a method, and num an object, the num = num++; would have behaved the way Tokamak and I would expect it to.

Definitely not. Consider this class:

class MyInt {
    private int value;
    public MyInt(int value) {
        this.value = value;
    }

    public MyInt postInc() {
        int oldValue = value;
        value = value + 1;
        return new MyInt(oldValue);
    }
}

This definition of postInc will behave exactly like ++ behaves for primitive ints. More importantly: there is no way to change the defintion of postInc so that it would behave the way you expect/want it to.

---

Another thing: I know I'm repeating myself, but several people in this thread have now referred to "the way that it works in C++" and I just want to reiterate that there is no way in which it works in C++. A C++ application in which you use this construct invokes undefined behavior - it might very well behave the same way as a Java application - or it might crash. The fact that on some implementations it produces the output you expect is a mere coincindince and certainly not a deliberate design decision made by the C++ comittee.

And again: if = introduced a sequence point, the behavior would be as in Java. So the only two options how x = 0; x = x++; might behave in a language that defines ++ the way that Java and C++ do are a) undefined or b) 0 as in Java. "c) 1" is not an option because it would be incosistent with the defintiion of ++.

As another example showing that, barring UB, C++ behaves the same way as Java, consider this:

#include <iostream>

int x;

void f(int y) {
    std::cout << "x = " << x << "; y = "<< y << std::end;
}

int main() {
    x = 42;
    f(x++);
    return 0;
}

I assume that you'd expect this program to output "x = 42; y = 42" (because you'd expect x to only increment after the call to f, but the actual output is "x = 43; y = 42". Unlike x = x++;, this behavior is fully defined and thus obviously consistent with the definition of ++. It's also exactly the same as in Java.

---

I also want to say that arguing "It has been done that way it's been done and that's that" is, in my opinion, not a productive way to reason about language design decisions. Design decisions are made for a reason and it is perfectly valid to discuss those reasons and whether or not there were better reasons to go another way. There are certainly some design decisions in Java where I firmly believe that going another way would have led to a much better developer experience (type erasure for example).

That said, I do not believe the decision to define ++ the way it has been defined was wrong in any way. I again want to emphasize that it's defined the same way as in C and C++ (and every other langauge that has the post-increment operator). Defining it differently than those languages (by actually saying something like "do something with x and then increment x afterwards"¹ in the spec, for example) would break the expectations of programmers coming from those languages. You might argue that C and C++ actually act differently in this particular case, but again: it's UB. They might very well behave the same way as Java in some implementations. And more importantly: changing Java's spec to behave the way you expect it to (without introducing UB), would cause Java to behave differently than C and C++ in many instances that are perfectly defined bheavior (like the example above).

¹ Note that this would still require you to define exactly when "afterwards" is, which is non-trivial.

Edited by sepp2k

0

sepp2k, thansk for your elaboration. I certainly agree with most of what you say and find interesting your explanations. I failed to declare all of my assumptions when I said "If ++ was a method, and num an object, the num = num++; would have behaved the way Tokamak and I would expect it to." and I see how that raised questions that your MyInt class answered. Anyways, thanks for your input.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.