Search code examples
cpost-incrementpre-increment

I don't understand the output of this code


I'm currently learning C, and my teacher gave us some homework. We had to identify the output of some code. I don't understand how y=4.

The code is as follows

int main() {

    int w = 3, y = 3;
    printf("w = %i\n", --w + w--);
    printf("y = %i\n\n", y = w + y++);

    return 0;
}

Solution

  • Let me preface this with an important public service announcement:

    When your compiler gives you a warning, any warning, you would do well to pay attention to it. The code example in your question gives rise to Undefined Behavior - in other words, the C standard does not guarantee that every compiler will give the same results, given your code. That is Always a Bad Thing.

    With that out of the way, here is an explanation of what is going on.

    I modified your code slightly to look at the intermediate value of w:

    #include <stdio.h>
    
    int main(void) {
    
        int w = 3, y = 3;
        printf("w = %i\n", --w + w--);
        printf("w is actually %d\n", w);
        printf("y = %i\n\n", y = w + y++);
    
        return 0;
    }
    

    My compiler complains about this code with the following warnings:

    order.c:6:24: warning: multiple unsequenced modifications to 'w' [-Wunsequenced]
        printf("w = %i\n", --w + w--);
                           ^      ~~
    order.c:8:35: warning: multiple unsequenced modifications to 'y' [-Wunsequenced]
        printf("y = %i\n\n", y = w + y++);
                               ~      ^
    2 warnings generated.
    

    And the output is

    w = 4
    w is actually 1
    y = 4
    

    What is happening? Since compilers parse the statement left-to-right, the statement

    --w + w--
    

    seems to result in the following steps (for my compiler):

    --w  : decrement w, it is now 2
    w--  : use the value of '2', but decrement w when you are done
    

    The result is that the sum is 2+2 and the first line prints 4, but after the sum is evaluated w is decremented to 1. However you cannot rely on this behavior - which is why the compiler threw a warning. As Eric Postpischil pointed out there may be situations where the order of execution might be different. "Don't do it" is the bottom line - you are courting Undefined Behavior.

    Note that the fact that your program printed w equals 4 doesn't mean that this was true at any time. As you can see, when you actually print out w it is 1.

    Assuming the compiler executed these statements in the above order, we go to the next line:

    y = w + y++
    

    We start with w = 1 and y = 3. The sum of these two is 4, and that is the value of the expression

    y = w + y++
    

    which is therefore what is printed (4).

    As a side effect, y is incremented. As it happens, either way the value of y is 4 at the end. If you change the code so you start with w = 5, you end up with y = 6. In other words, the effect of y++ got overridden by the y = assignment.