6

I have the following code source in C:

#include<stdio.h>

void main()
{
    int i=0, x=3;
    while((x---1))
    {
        i++;
    }
    printf("%d", i);
}

How does this while statement work and why does it print 2 instead of 1?

Dog
  • 474
  • 8
  • 25
  • 6
    I still like the `-->` operator better: `while(x-->0) {...}` – nneonneo Jul 30 '13 at 14:07
  • 2
    @nneonneo Suggests "x goes to zero" :) Mathematicians and IOCCC submission authors gotta love that. –  Jul 30 '13 at 14:10
  • 1
    I've used it myself in toy testing code because it's just so much easier than typing the equivalent for loop. But, maintainers will probably kill me if I try to submit it for real :) – nneonneo Jul 30 '13 at 14:11
  • 1
    I can't imagine why you would expect it to print 1. You ought to explain your thinking. – Jim Balter Jul 30 '13 at 15:27

4 Answers4

10

Because x---1 is really just x-- - 1 which yields the value of x - 1 before decrementing x.

Given that x has an initial value of 3, the loop runs 2 times (once with x = 3, once with x = 2, then next time x is 1, so x - 1 is 0, and the loop doesn't run anymore).

So, i starts at 0 and it's incremented twice, so it ends up being 2.

  • 1
    Thank you, I now realized that x is decremented only by the x-- statement. I don't know why I thought that it was decremented twice: once by the x-1 and after by the x-- statement. But since it's not x=x-1, it doesn't change its value by this one. Took me a while to get to it though :) – Dog Jul 30 '13 at 14:24
5

(x---1) == (x-- -1)

because compiler try to choose bigger token first, So --- interpreted as -- & -

Expression x-- - 1 means first 1 subtracted from current value of x due to - minus operation. Then x value decremented by 1 due to postfix decrement operator --.

For example in before first iteration x = 3, so while condition is 2 (that is 3 - 1) after that x decremented, and before next iteration x = 2.

x = 3, i =0;

  • 1-iteration: while(2), and in loop i becomes 1

x = 2, i = 1;

  • 2-iteration: while(1), and in loop i becomes 2

x = 1, i = 2;

  • Now, x - 1 = 0 that gives while(0) and loop breaks and i not increment.

So after loop output i: 2

note one more point: i does not increment as loop break because i++ in while-block {}, but x decremented to 0. After loop if you printf x then output will be 0.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
3

So the the while probably makes more sense if you look at it with some more spaces:

while( ( x-- - 1) )

It is using a post decrement so x is modified after returning it's current value so it is really equivalent to this:

while( ( x - 1) )

and the loop will run until the expression is false or in the this case 0 which is equivalent to false. So the run goes like this:

x   x - 1   i
=============
3     2     1    x - 1 not 0 so increment i
2     1     2    x - 1 not 0 so increment i
1     0     2    Loop exits here and does not increment i again

At this point the loop exits and you hit the printf.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
2

while((x---1)) is equivalent to while((x-- -1 != 0)), which in turn is the same as writing while(x-- != 1). Since the value of x-- is the value of x before the decrement, this is the same as

while(x != 1) {
    x--;
    ...
}

which runs twice if x starts at 3.

nneonneo
  • 171,345
  • 36
  • 312
  • 383