-4

Why doesn't the value of x increment in the following code?

#include <stdio.h>

int main(){

   int x = 3, i = 0;
   do {
       x = x++;
       i++;
   } while (i != 3);

   printf("%d\n", x);
}
helencrump
  • 1,351
  • 1
  • 18
  • 27
  • 2
    @FredLarson: at least it's the first time this is asked *in 2018*! – Jongware Jan 02 '18 at 17:11
  • 2
    @FredLarson Yes, it turns out that a lot of people don’t know everything, and there are some things that a lot of people don’t know because they’re confusing and/or poorly taught. Googling doesn’t help because different programming languages treat these concepts differently and even adding “c” to the search doesn’t limit the results to C. – Daniel H Jan 02 '18 at 17:11
  • 3
    @DanielH: true. We need to tell this to every single person, again and again. – Jongware Jan 02 '18 at 17:12
  • 1
    @DanielH this is not a bad question because the code is bad, (which it is), or because the OP has not done a diligent amount research, (which they have not), or because it's been asked on SO [FP overflow] times already, (which it has). It's bad because it's pointless. It's pointless because the confusing code in it is easily replaced with code that is clear and understandable. That's why it's bad. – Martin James Jan 02 '18 at 19:52

1 Answers1

3

In x = x++, you are saying both to increment x and to assign x a value. The C standard does not define what happens if you do both of these things “at the same time.” For this purpose, “at the same time” means your code has not arranged for one of them to occur before the other.

If you put the increment and the assignment in separate statements, the C standard says that one of them occurs before the other, and then the behavior is fully defined. Technically, there is a sequence point between two such statements. Sequence points are barriers that separate effects. Inside the single statement x = x++, there is no sequence point.

(There is more about sequence points and sequencing in C, but the details are beyond the scope of this question.)

In the simplest C implementation, the compiler might treat x = x++; as if it were x = x; x++; or as if it where int Temporary = x; x++; x = Temporary;. The first would set x to 3 and then to 4. The second would set x to 4 and then to 3. However, the C standard gives implementations a great deal of latitude. In some C implementations, integer types might be made up of parts—a small computer might not be able to handle 32-bit integers all at once, so it might have to do arithmetic in multiple 16-bit steps, or even multiple 8-bit steps. The C standard says, since you have not arranged for the assignment and the increment to occur in a particular order, then, not only is the implementation allowed to do them in either order, it is even allowed to mix the steps. It might do one byte of the assignment, one byte of the increment, the second byte of the assignment, the second byte of the increment, the third byte of the increment, the third byte of the assignment, and so on. In general, you could get a nonsensical answer that is a mishmash of operations on the parts.

So the C standard does not say that, if you do not arrange for the operations to be ordered, then either one happens before the other. It says, if you do not arrange for the operations to be ordered, we do not guarantee what will happen at all. You may get a big mess.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
mdatsev
  • 3,054
  • 13
  • 28
  • What is the right sentence then, I should say that they are both executed between the same 2 sequence points and thus the order is not defined? Or should I say in the same expression or statement? – mdatsev Jan 02 '18 at 18:05
  • C has already switched to a new sequencing model based of *sequenced before* and *sequenced after* relations (similar to the one used in C++). So, pedantically speaking, it is not correct to describe the situation in therms of *sequence points*. The concept still exists in C (*sequence point* is basically a combination of *sequenced before* and *sequenced after* concentrated in a specific point), but it is no longer sufficiently accurate. – AnT stands with Russia Jan 02 '18 at 18:14
  • @AnT: Can you pack it into simple sentences that newbies understand and get it into an answer that will be voted up? Stack Overflow is not good at this. The new model may have more descriptive power and precision, but how do you teach it to people who are still learning elementary issues like this? And, if you can teach it, how do you get an answer accepted when you come along after somebody has already entered a simplistic answer that is voted up? On top of that, we will have to prevent people from marking post-2011 (C standard) questions as duplicates of pre-2011 questions. – Eric Postpischil Jan 02 '18 at 18:49
  • You can expand my answer if you want since I don't have the knowledge of the new model. – mdatsev Jan 02 '18 at 18:52
  • 1
    @mdatsev: I rewrote it to comply with the current standard, I think, while still trying to keep the concepts suitable for a student. If you wish, you can revert my edit to the previous version. – Eric Postpischil Jan 03 '18 at 01:07