A student of mine wrote the following code:

    public class Counter{
       private num = 0;
       public void inc(){
          num = num++;
       }
    }

which fails to increment.

Why? If num starts at 0, then the assignment should be num = 0 then num should increment during the postfix incrementation of num!? (of course any experienced programer would have written simply num++)

public class Counter{
   private num = 0;
   public void inc(){
      num = ++num;
   }
}

Naturally, works due to the fact that prefix incrementation takes place before assignment.

@OP
Your student? If you have a masters+ degree in Computer Science or a related field, and are teaching a programming course; I find it hard to believe that you can not answer this question...

Edited 3 Years Ago by pbj.codez

Just in case this is a real question, here's a real answer:
No, it doesn't fail. It does exactly what the Java Language Spec says it should.

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.

and 15.26 (Assignment operators)

the right-hand operand is evaluated ... the value of the right-hand operand is converted to the type of the lefthand variable ... the result of the conversion is stored into the variable.

Edited 3 Years Ago by JamesCherrill

I do not think that the people who downgraded this question understood the nuances of the question.

It is a real question. I am a software engineer with a Masters Degree in EE and I am computer professor at a Community College. I have 30+ years of programming experience and I do not understand all the details of this equation.

My understanding was the first the assignment happens so num gets zero then incrementation of num happens so num should be one.

For example I often show my students this code:

z = 0;
y = z++;
System.out.println(" y = " + y + " z = " + z);

which prints:

y = 0 z = 1

The code one of my students wrote was the same code except that num replaced y and z. In my mind, since z becomes one num should become one after the assignment.

Can anyone explain in detail why, if num++ is evaluated last (just as z++ was evaluated last), num fails to increment? I am guessing that num++ never gets evaluated after the assignment.

And no I am not "bashing the student". I actually congratulated him on stumping me and suggested n++; or num += 1; as a fix. I said I thought daniweb was a good place to get an answer to the question of exactly what happens.

I was going to show the answer in class tonight.

Edited 3 Years Ago by TokamakFusion

Comments
I have had the same problem

@OP
I still feel like, you may have just copied someone elses work, posed as a professor, and want us to explain their code. If you really have 30+ years of experience in the programming field, this should be a walk in the park to answer for yourself. As a result, I'm not going to answer your question. Goodluck

Edited 3 Years Ago by pbj.codez

LOL - you still do not understand the problem.

When I write this in C++

#include <stdlib.h>
#include <iostream>
using namespace std;

int main( void )
{
    int num = 0;
    num = num++;
    cout << num;
    system("pause");
   return 0; 
} 

I get 1.

Which is the behavior I expect. Sorry you do not get it.

Edited 3 Years Ago by TokamakFusion

If num starts at 0, then the assignment should be num = 0 then num should increment during the postfix incrementation of num!?

The increment happens before the assignment. Postfix increment does not mean that the increment happens after the current statement. It only means that the result of the expression will be the value of the variable before incrementing (as you can see in the quote of the specification posted by James).

Basically if you have foo(x++) that's equivalent to oldX = x; x += 1; foo(oldX), not foo(x); x += 1;. So x = x++; is the same as oldX = x; x += 1; x = oldX, not x = x; x += 1.

I still feel like, you may have just copied someone elses work, posed as a professor, and want us to explain their code.

He already knows that replacing num = num++ with just num++ will fix the problem, so how would explaining why num = num++ doesn't work, help him take advantage of someone else's work?

When I write this in C++ I get 1

The C++ code invokes undefined behaviour. You might very well get different results on other implementations. If the behaviour were defined (i.e. if = introduced a sequence point), you'd get 0 just like in Java.

By the way, do not feel bad that you did not get the problem. With my education and experience it has me stumped, too.

num = num++;

should (as it does in C++) assign num to num then increment num.

I believe my student discovered a mistake in Java and thought that someone here could tell me if it was a mistake or a "feature" :) or if there was something I was missing.

Its stuff like this that makes programming interesting...

"The C++ code invokes undefined behaviour. You might very well get different results on other implementations. If the behaviour were defined (i.e. if = introduced a sequence point), you'd get 0 just like in Java"

Ah HA! That sounds like the correct answer. Just like
int x;
may give 0 or 34579
depending on the compiler!

Thanks.

should (as it does in C++) assign num to num then increment num.

actually, that is what is happening, but not the way you thought it would.

in the line:

num = num++;

you're working with (what might be considered as) two different variables, numNow and numResult.

it's actually like:

numResult = numNow++;

or, to write it out, it's a bit like this:

numResult = num;
num = num + 1; // after the assignment of num to numResult
num = numResult;

I believe my student discovered a mistake in Java
...
num = num++; should (as it does in C++) assign num to num then increment num.
...
invokes undefined behaviour.... Ah HA! That sounds like the correct answer. ... depending on the compiler!

From the above quotes I suspect you do not have the correct answer in your mind. The behaviour is not a mistake, c++ is irrelevant, and the behaviour is not undefined or compiler-dependent.

The Java Language Specification makes it perfectly clear what the behaviour should be, and what you observe is exactly what the JLS says it should do. No mistake, no ambiguity, no possibility of variation for any valid java compiler. Please refer to the JLS sections that I posted earlier.

I have sympathy for the student whose teacher doesn't know fundamentals of the language like this...
_____________________

LOL it is amazing how many people on this site are ready with a put down while they do not understand the problem.

It works correctly in C++ but not in Java.

num = 0;
num = num++;

should return 1.

Earlier I thought it might be a java compiler issue - have seen a few of those over the years... but IMHO Java did it wrong.

Edited 3 Years Ago by TokamakFusion

Comments
it works correctly in both, but you don't seem to understand that Java IS NOT C++
Still doesn't understand the answers he has been given.

It works correctly in C++ but not in Java.

I said this already, but I'll say it again: The C++ code you posted invoked UB. If it had not invoked UB (i.e. if = introduced a sequence point), the behavior would be the same as in Java. Java's behavior is correct (i.e. completely in line with ++'s definition). The C++ behavior was the one that's "wrong" (i.e. incosistent with the definition of ++) because UB programs can behave anyway they want and in this case it decided to act in a way that's not consistent with ++'s definition.

Note that Java's definition of ++ and C++'s definition of ++ are the same. The only difference is that in C++ modifying the same variable twice without a sequence point in between invokes UB. Otherwise the definition of ++ in C++ would mandate that your C++ code should print 0 just like your Java code.

To illustate this, consider this code:

#include <iostream>

void assign(int& target, int value) {
  target = value;
}

int main() {
  int y = 0;
  assign(y, y++);
  std::cout << y << std::endl;  
}

The only difference between that code and yours is that I used an assign function to introduce a sequence point rather than using = directly. And this program will always output 0.

So if it is undefined behavior how can C++ be wrong? And how can Java's behavior be right?

I like your example; It is a very good exposition of your point. And I agree that in your example you would always get 0.

IMHO

num = 0;
num = num++;

should be defined to return 1. Which from my point of view makes C++ right and Java wrong.

Shrug.

Edited 3 Years Ago by TokamakFusion

You are entitled to your opinion, BUT, when the process is EXPLICITLY defined by the JLS to NOT do that, it doesn't really MATTER what your opinion is.

Edit: Also, you STILL do not seem to have grasped the fact that C++ "works" that way IN THE CURRENT IMPLEMENTATION of the C++ specs that YOU ARE USING. Other implementations may NOT work that way, as C++ DOES NOT DEFINE how the process is to work.

Edited 3 Years Ago by masijade

So if it is undefined behavior how can C++ be wrong?

Well, obviously it's legal behavior, but it's not consistent with the definition of ++. That is the UB is unrelated to the fact that you're using ++ and due to the UB it behaves in a way that does not follow the definition of ++ (and of course it might very well act differently on other implementations). Without the UB, it would have to produce 0 because that's what the definition of ++ mandates.

should be defined to return 1. I say this because it is consistant with the definition of postfix notation.

No, it is not. x++, as it is defined in both Java and C++, evaluates to the value of x before the increment. So if x is 0, x++ evaluates to 0. Now, barring UB in C++, foo = bar will evaluate the expression bar before the result is assigned to foo (which makes sense since obviously you can't assign the result of bar to foo without evaluating foo first). This means that if you do x = x++, first x++ is evaluated (causing x to become 1) and then the result of the expression (0) is assigned to x. Thus x ends up being 0.

Any other result you might get in C++ is incosistent behavior due to UB. The above behavior is the only one that's consistent with the definition of ++.

After some time I have some thoughts on this discussion.

Some of you are blinded to the fact that num = 0; num = num++; can be read to give 1.

I understand what everyone is saying, but there is a reason it is undefined in C++. My interpretation that it should return 1 is a valid one and the general consensus here that it should return 0 is a valid one. That is probably why it is undefined in C++. I think it was a mistake to define it in Java as returning 0. A better approach would have been to leave it undefined or illegal. It is a non-sense construct after all.

When I made my original post I was subjected to some extremely rude behavior. I do not think that attacking a poster and his or her grasp of computer science is a way to attract posters or readers for that matter.

I was pretty upset at being called a fake and a bad professor over this issue. I did not come here to invite ridicule but rather to have a Socratic discussion on the issue.

I have a lot of valuable insight into problems I have seen posted here but will probably not be back.

You have lost the input of a former University Of Pittsburgh faculty member who has taught Carnegie Mellon computer programming courses. I have been a Community College professor for 13 years. I spent years writing code in the nuclear industry and years doing so as a consultant. I do have insight into problems that beginners and advanced programmers run into.

I used to recommend your site to students but after, seeing the type of behavior that goes on here, I will not do so in the future. I do not want to see them subjected to abuse for just asking a question. I am 61 years old and probably not as sharp as I once was but I am smart enough to avoid places where juvenile behavior is an accepted norm.

LOL – after seeing the way things go here, I expect some asinine responses to this post – which I most likely will not see as I do not plan on coming back to this site. Of course those of you for whom the shoe fits could do the mature thing and accept the valid constructive criticism and change your behavior making the site better but I have serious doubts that that will happen.

Edited 3 Years Ago by TokamakFusion

... actually:
<bit_of_rant>

My interpretation that it should return 1 is a valid one

when we're talking about Java, you (being a Java teacher, or so you claim) you should know perfectly well that it is NOT a valid one. mainly, because that is not how it was implemented by the creators of Java, and which is well documented.

I think it was a mistake to define it in Java as returning 0.

seriously, this comming from a Java teacher? I think it was a mistake for evolution to give us just two feet, while we could run a lot faster with an extra set, but since that's not the case .... whining about it won't change a thing.

I was pretty upset at being called a fake and a bad professor over this issue.

really didn't see that comming? posting things like that (my above two remarks, for instance) is simply asking for it. you ignore Java itself, you apparently don't seem to understand that certain things are implemented, and you expect us to think you are a professional while you are stating that "Java should work the way you think it should, and that the actual implementation is plain wrong" ...

I have a lot of valuable insight into problems I have seen posted here but will probably not be back.

You have lost the input of a former University Of Pittsburgh faculty member who has taught Carnegie Mellon computer programming courses. I have been a Community College professor for 13 years. I spent years writing code in the nuclear industry and years doing so as a consultant. I do have insight into problems that beginners and advanced programmers run into.

I useto recommend your site to students but after, seeing the type of behavior that goes on here, I will not do so in the future. I do not want to see them subjected to abuse for just asking a question. I am 61 years old and probably not as sharp as I once was but I am smart enough to avoid places where juvenile behavior is an accepted norm.

Our loss, no doubt..
but, then again, your initial post contained wrong information. "which fails to increment" ... no, it doesn't fail to increment, it just increments after the assignment. I can just hope that in your classes, you give your students correct information, and not the "which fails to increment", "it should return 1", ... explanations you've given here and are clearly not correct when it's about Java.
you are smart enough to avoid places where juvenile behavior is an accepted norm ? well, not willing to admit you are wrong, and not planning on taking correct information and improving your knowledge (which is basically what you are doing) can also be seen as 'juvenile behavior'.
I'm a frequent visitor of this page, and I can assure you that I've had a lot of help from posts made here.

Thousands of volunteers who give up their spare time to help others solve their problems and improve their knowledge/chances on the job market, without asking for anything in return, except maybe a bit of appreciation (which isn't even mandatory), but you're not even considering the option that the posts you were given were trying to explain to you that (and why) you are wrong.
you have your idea about how Java works, and, unfortunately, that idea isn't completely correct. you've been corrected time and time again, yet you are not willing to see anything but "they are criticizing me", and stick with your wrong ideas, simply stating "you don't want to tell me that I'm right? then I'm leaving this page." indeed, very mature.

personally, I'm afraid to learn about the degrees you get to hand out about Java. in this thread, it 's shown clearly that your knowledge of Java is, how to say it ... a bit dodgy, so I can only imagine how you correct their assignments, or judge on their exam results.

which I most likely will not see as I do not plan on coming back to this site. Of course those of you for whom the shoe fits could do the mature thing and accept the valid constructive criticism and change your behavior making the site better but I have serious doubts that that will happen.

I think I'll survive the thought of not seeing any more of this kind of threads. nobody forces you to stay or to re-visit this page. might indeed be, as you stated, that we loose a valuable member, but then again, I think it's a risk most of us are willing to take.
"those of you for whom the shoe fits could do the mature thing"
well, read my thoughts in the previous remark. you want us to do the mature thing, while you're acting like a stubborn child yourself? everybody here being mature, as long as posts like your appear here, and there are members with an attitude like yours, I also have "serious doubts that that will happen".

</bit_of_rant>

my apologies for an indeed not overly mature post, but then again .... I can't say I've said anything I don't stand behind.
It's too bad but indeed, there will always be those not appreciating the help being given, but I'm gratefull to know (as a member for years now) that this represents only a small percentage of the members.

stultuske's <bit_of_rant> pretty much covers what most (all?) of us here feel, so guys please let this one drop now. Let's all move on to topics where people are willing to listen, contribute and learn.

J

Which from my point of view makes C++ right and Java wrong.

and again you're wrong, as in C++ it's not defined to do anything at all, so whatever it does is utterly random, depending on the whiles of whoever wrote that specific piece of the compiler, which might well change between compiler versions.

undefined behaviour does not equal legit code or 'it works.'

Quite why you making this comparison to back yourself up is crazy. You shouldn't be teaching period. Instead you should take up a role in the circus... As a clown.

Edited 3 Years Ago by iamthwee

I have encountered this same issue once, and I happened to have access to someone that other people told me is a guru at the time. And I do take that guy for a guru, but this exact question puzzled him also, so all you much respected Java Forum helpers are a little wrong with your reactions to Tokamak, let me tell you straight forward.

Anyways, this is how the guy I mentioned went about the issue:
he used javap to see the assembly equivalent of the code (correct me if I am wrong with the interpretation of what he did), and tried to see what is actually going on.

Now, with all that specs referencing going on, what the conversation seems to have made necessary is to discuss how the specs are actually implemented.

I do agree with Tokamak that the c++ example he mentioned is closer to how my intuition expects the code to work than Java. I know that the question is solved, but I just wanted to put in my two cents.

AND, as someone that has been paid 12 salaries as a programmer (that is my experience), but is very interested to make sense of ins and outs of programming, here is how I'd speculate and try to make sense of this issue:

Java is very rigid in discerning between Objects and primitive types. If ++ was a method, and num an object, the num = num++; would have behaved the way Tokamak and I would expect it to. But since, num is of a primitive type, my guess is that num = num++; created a new block in memory for num++ and modifies it to the value of num++ only after assigning num from the new place in memory to num in the original place in memory. It is very likely I am wrong, but I do not really care if I am or not. What I care is to learn how this actually works.

kind regards guys.

bibiki: saying 'Java is wrong here', was wrong. which is what Tokamak said.
no, it is not wrong. the creators of Java chose to implement it in a certain way, and that is basically all that's to it.

when you compare the functionality to that of another language, yes, it might differ, but that doesn't mean it's "wrong", it just means the implementation is not the same.

your, or Tokamak's for that matter, intuition are not really the 'rules to follow' by a Java compiler or the JVM, the Java specifications are, and yes, it might be possible they're not entirely the way you think/hope/expect they are, but that doesn't change them, nor does it make them wrong. To me, that just comes over as: "I have a Ferrari, so my intuition tells me that I should drive 170 km/h, so, officer, you can shove off with that speeding ticket."
There are times when I question for myself a certain implementation, but it wasn't my call. Best thing I can do at that time is learn what it does (in this case: in which order) and try to understand why it does it in that way/order.

Tokamak was contradicting the Java specs, and telling us that "Java behaving wrong" and had a "flaw" in it, basically just because he is not as familliar with Java as he should have been (seeing he teaches it). The increment works perfectly fine, but, it is a post-increment, and, since he is a Java teacher, he should know that a pre-increment and a post-increment do not work in the exact same way.

This question has already been answered. Start a new discussion instead.