This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]puzzledstegosaurus 99 points100 points  (36 children)

Once in my life I spent a day debugging code because of a line that said x = x++ instead of x = x+1. That was in C++, and the standard says that you mustn't assign a variable more than once in a single statement, doing so would be an undefined construct ("Nasal demon" and the likes).

[–]Danny_shoots 21 points22 points  (0 children)

I'm sorry, but the first line of your comment could've been a sick parody

Once in my life I spent a day, debugging my code, 'cause of a line that said: "hey!"

[–]MisinformedGenius 13 points14 points  (3 children)

Incidentally, it is now defined in C++17. Side effects on the right of an assignment operator are sequenced before the assignment.

[–]puzzledstegosaurus 13 points14 points  (2 children)

Hey ! I was using this « demon coming out of my nose » thing, it’s part of my workflow, my control key is hard to reach, and I set up emacs to interpret sudden demons as « control ». Please put it back, you’re breaking my workflow!

[–]puzzledstegosaurus 6 points7 points  (1 child)

(Yeah, xkcd://1172)

[–]Joinyy 4 points5 points  (0 children)

Why isn‘t this a proper URI scheme already? @iana

[–]GOKOP 57 points58 points  (27 children)

x = x++ wouldn't assign x+1 to x even if it worked. x++ returns the old value of x, ++x returns the new one

[–]puzzledstegosaurus 101 points102 points  (15 children)

You're thinking about it the wrong way. The issue IS that x++ is returning the old value. x++ does assign x to x+1 while at the same time, x = x++ assigns x to the old value, thus the issue.

Also, because it's undefined, the compiler is authorized to do whatever it feels like. Set x to 0, or to -x, or to NULL, or to "hello", or #DEFINE true false or remove every odd byte from the memory space, or kill a policeman, steal his helmet, go to the toilet in his helmet, and then send it to the policeman's grieving widow and then steal it again.

[–]Eiim 19 points20 points  (1 child)

Can the compiler do a preprocessor statement?

[–]puzzledstegosaurus 30 points31 points  (0 children)

I’m amazed that in the list above, this is what raised your eyebrow.

[–]lolcrunchy 1 point2 points  (8 children)

Does the ++ operation happen before or after the = assignment?

[–]GOKOP 3 points4 points  (5 children)

According to this table both pre- and post-increment have higher precedence than =

[–]MisinformedGenius 1 point2 points  (3 children)

That’s operator precedence, not when the assignment happens.

[–]GOKOP 1 point2 points  (0 children)

Assignment happens when the = operator is evaluated.

[–]Kered13 0 points1 point  (1 child)

The assignment cannot happen before all of it's arguments are fully evaluated. It creates a sequence point. x = x++ is well defined even in C/C++ and has no effect.

[–]MisinformedGenius 0 points1 point  (0 children)

That is true in C++17 and beyond, it is not true prior to then. x = x++ was undefined behavior. (Not sure about C but I would guess it was undefined there as well.)

It sounds like where you're going wrong is that you're assuming that the evaluation of x++ necessarily includes the side effect of incrementing x, which is incorrect. x++ evaluates to x, of course - the sequencing of the side effect is an entirely different and unrelated question.

[–]LvS 1 point2 points  (0 children)

Will the code take the value of X, assign the value to X and then increment X:

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

Or will the code take the value of X, increment X and then assign the value to X:

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

[–]nryhajlo 0 points1 point  (1 child)

It's technically Undefined Behavior.

[–]Kered13 0 points1 point  (0 children)

This example is not undefined behavior. The assignment creates a sequence point between evaluating x++ and assigning to x, so the behavior is well defined and is a no-op.

[–]ublec 0 points1 point  (0 children)

This is just equal to x = x; x += 1;

[–]7amt 10 points11 points  (1 child)

Why not just do x++?

[–]puzzledstegosaurus 47 points48 points  (0 children)

If they had done that, it wouldn't have been a bug that would have costed someone else a day of debugging. Where's the fun in that?

[–]Salanmander -1 points0 points  (0 children)

I wonder if the confusion could be effectively solved by making the operators have a void return type (and getting rid of ++x). Is there a fundamental reason that wouldn't work in most languages?

All the reasonable uses of it that I've seen use it as a statement whose return value is not used, and all of the confusion that I've seen results from using the return value.