Search code examples
cparameter-passingoperator-precedenceexpression-evaluation

Postfix increment operator evaluation


Are postfix increment/decrement operators evaluated after the expression is evaluated or after the entire statement is evaluated ?

#include<stdio.h>

void main()
{
  int a=0;
  int b=0;

  printf("%d %d",a||b,b++);  // Output is 1 0

}

My compiler evaluates the printf arguments from right to left. The answer of expression a||b is 1, it means that b has incremented before a||b has been evaluated(i.e b is incremented immediately after evaluating the expression b++)

I read here Incrementing in C++ - When to use x++ or ++x? that postfix increment/decrement are evaluated after the entire statement.

Which is correct?


Solution

  • The order of evaluations of function arguments is unspecified. All side effects related to the argument evaluations are applied before the control will be passed to the called function.

    From the C Standard (6.5.2.2 Function calls)

    10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call.

    Here is a demonstrative program

    #include <stdio.h>
    
    struct 
    {
        int x;
    } a = { 0 };
    
    void f( int x )
    {
        printf( "x = %d\n", x );
        printf( "a.x = %d\n", a.x );
    }
    
    int main(void) 
    {
        f( a.x++ );
    }
    

    Its output is

    x = 0
    a.x = 1
    

    Due to the side effect in this call then one argument is dependent on a side effect of other argument and the evaluation of the side effect indeterminately sequenced relative the arguments

    printf("%d %d",a||b,b++);  
    

    the program has undefined behavior.

    There are four operators in C when side effects are sequenced between operand evaluations. They are the logical AND operator (&&), logical OR operator (||)comma operator (,), and the conditional operator ( ?:).

    For example

    #include <stdio.h>
    
    int main(void) 
    {
        int x = 0;
    
        printf( "x = %d\n", x++ == 0 ? x : x - 1 );
    }
    

    The program output is

    x = 1
    

    The side effect of the evaluation of the expression x++ was sequenced before the evaluation the expression x after the ? sign.