-1
#include<stdio.h> 

int main() 
{ 

    int i = 1; 
    
    printf("%d %d %d",++i,i++,i); 
    return 0; 
} 
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
First last
  • 29
  • 5

2 Answers2

1

(not an answer, but further discussion)

It really seems like an interesting question (at least for me, as I am also a C newby).

I tried the following snippet:

//gcc 7.4.0
#include<stdio.h>
int main() {
int i = 1; 
printf("%d %d %d\n",pr(++i),pr(i++),pr(i)); // 3 1 1
i=1;
printf("%d %d %d",++i,i++,i); // 3 1 3
return 0; 
}
int pr(int v){
  printf ("arg: %d\n",v);
  return v;
}

And was shown (for the upper case)

arg: 1
arg: 1
arg: 3

I still don't understand why my two printf() statements yield different results.

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • 2
    The C standard says about **Expressions** that the evaluations of the actual parameters of a function call are _unsequenced_. _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._ – Armali Feb 27 '21 at 09:41
  • Right. When you look at that first printf, you have probably decided in your mind which of those pr() calls will be made first. The C and C++ standards do not dictate that. Many stack-based compilers start evaluating the last parameters first, because they have to go on the stack first. That's what you're seeing here. – Tim Roberts Feb 28 '21 at 01:21
  • As mentioned before, my post was never meant to be an "answer" but simply another demonstration that the processing order of the arguments is "undefined". I _do_ get the point now, obviously. I will gladly pay the price of the downvote for it and hope it will help other readers. ;-) – Carsten Massmann Feb 28 '21 at 05:09
0

Your program exhibits what the spec calls "undefined behavior". This is not a valid C program, because you are not allowed to modify a single variable twice within a single statement. A compiler is allowed to handle this however they want. You will get different results with different compilers. Some compilers might produce "3 1 3", some might produce "3 1 1", some might produce totally random numbers.

It's important to understand this. Even if YOU can see how to produce a certain result, the compiler is allowed by the spec to do anything at all.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • Interesting point, this clearly differs from JavaScript. Is it the same in C#? – Carsten Massmann Feb 27 '21 at 08:06
  • JavaScript and C# both mandate strict left-to-right evaluation of expressions. That mandate allows there to be an unambiguous answer. C and C++ do not mandate that, which allows the compiler freedom to do more extensive optimizations, but it also means that some expressions have undefined behavior. – Tim Roberts Feb 28 '21 at 01:18