-1
#include <stdio.h>

int main ()
{
    int a = 1;
    printf("%d\t%d\t%d\n", ++a, ++a, a++);
    printf("%d\t%d\n", a++, ++a);         
    printf("%d\n", a);                    
    
}

Following are the points which I followed when I did dry run check:

  1. associativity is from right to left (<------)
  2. Whenever I'm using same type of increment operators (say ++a in 1st printf line), the recent value is getting updated for both (like the integer 4 is updated in the 1st printf line)

According to my logic, the commented one is the output that I expected.

But the actual output is: 4 4 1 5 6 6

Am I applying the wrong logic?? Can anyone please explain.

#include <stdio.h>
int main()
{
    int a = 1;
    printf("%d\t%d\t%d\n", ++a, ++a, a++); // 4    4    1
    printf("%d\t%d\n", a++, ++a);          // 5   5
    printf("%d\n", a);                     // 6
    
}
jps
  • 20,041
  • 15
  • 75
  • 79
SAMPATH
  • 9
  • 1
  • @SAMPATH The code has undefined behavior. – Vlad from Moscow Mar 26 '23 at 09:13
  • 1
    Your logic does not matter, you are invoking undefined behavior. You need to learn about [sequence points](https://stackoverflow.com/questions/3575350/sequence-points-in-c). – Elliott Frisch Mar 26 '23 at 09:14
  • Don't waste your time on this, code like this has no practical use anyway (had it worked). – BoP Mar 26 '23 at 09:32
  • Associativity does not apply here. Associativity applies to operators like `+`, not the arguments to a function call. And associativity doesn't determine the order that the *subexpressions* happen in, either. And when the subexpressions step on each other, like when two of them both do something like `++a`, the results are *undefined*. – Steve Summit Mar 26 '23 at 14:59
  • IMHO the indicated duplicates do not cover this question because without understanding that there are no sequence points between the evaluation of function arguments, it cannot be understood why the multiple occurrences of `a++` cause undefined behavior (only the latter is covered by the duplicate). I have tried to write an answer covering both aspects. – nielsen Mar 26 '23 at 15:12

1 Answers1

0

The order in which function arguments are evaluated before the function is called is unspecified behavior. You are assuming a sequence point between each argument, but that is not specified by the C Standard (C99, §6.5.2.2-10):

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

In C17, §6.5.2.2-10 the wording is different, but the result the same as far as this question is concerned:

There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

This means that the compiler is free to evaluate function arguments in any order, so on a different system, a different compiler or the same compiler with different options enabled, you may see a different result corresponding to a different order of evaluating the function arguments.

Note that the order of evaluation of arguments is unspecified behavior, not undefined behavior.

However, having more than one (sub)expression modifying the same variable without being separated by a sequence point is undefined behavior. C17, §6.5-2:

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

Hence, the first two printf-statements having more occurrences of a++ have undefined behavior and thus the C Standard does not guarantee any outcome of the program.

nielsen
  • 5,641
  • 10
  • 27
  • Does the order of argument evaluation need to be Consistent / Stable? Can arguments be evaluated in different orders during a single run?! Or must the evaluation be consistent at least until the next compile/link/run cycle? – abelenky Mar 26 '23 at 13:56
  • @abelenky There are no guarantees. In principle, the compiler could base the order on a random number each time that part of the code is executed. Btw., I noticed that I missed completing this answer so I have updated it to explain why the OPs code actually ends up in undefined behavior and not just unspecified behavior. – nielsen Mar 26 '23 at 15:06