-1

I have been trying to understand how printf processes the arguments that are passed to it. To be more specific can someone please explain how the following outputs occour.

int a=1;
printf("%d %d %d",++a,a,a++);// outputs: 3 3 1

a=1;
printf("%d %d %d",a++,a,a++);// outputs: 2 3 1

a=1;
printf("%d %d %d",a,a,a++);// outputs: 2 2 1

a=1;
printf("%d %d %d",a,a++,a);// outputs: 2 1 2

a=1;    
printf("%d %d %d",a,a,++a);// outputs: 2 2 2

the same output occurs with the cout statement.

simonc
  • 41,632
  • 12
  • 85
  • 103
Shivhari
  • 53
  • 3
  • 7
    Ah..... it's been too long. (And this has *nothing* to do with `printf`.) – Kerrek SB Apr 25 '13 at 11:38
  • 1
    Order of evaluation of the parameter is not fixed. – BLUEPIXY Apr 25 '13 at 11:41
  • 2
    @KerrekSB It's not quite up there with `while ( !file.eof() )...`, but it's close. (Of course, the answer to the question in the title is: it uses ``. But that's not the question he actually asks.) – James Kanze Apr 25 '13 at 11:46

2 Answers2

4

This code

printf("%d %d %d",++a,a,a++);// outputs: 3 3 1

modifies a twice in the same expression. To be precise it modifies a twice without an intervening sequence point. Because of this this code has undefined behaviour and any attempt to reason about it is futile. The compiler can do what it wants, and different compilers will do different things. See undefined behavior and sequence points for a detailed explanation.

With code like this

printf("%d %d %d",a,a,a++);// outputs: 2 2 1

it's undefined exactly when a++ is incremented, it could be before or after a is used for the other arguments. So your output could vary.

The only real thing to understand here is don't write code like this. Follow that rule and you won't go wrong.

Community
  • 1
  • 1
john
  • 7,897
  • 29
  • 27
  • If I'm not mistaken, "sequence point" is mentioned in C++03, but was reworded in C++11. Some rules (including this one?) changed as well. I see @sftrabbit's answer concurs with this, and it is not undefined behavior in C++11 if I'm not missing something (which is very well possible). – rubenvb Apr 25 '13 at 11:42
  • @rubenvb I haven't kept up with C++11 but sftrabbit says it's undefined in C++11 as well. – john Apr 25 '13 at 11:46
  • 1
    @rubenvb - the terminology changed, but the goal was to leave the underlying rules the same for single-threaded code. – Pete Becker Apr 25 '13 at 11:49
  • 5) i = ++i + 1 ; //well defined behaviour 6) ++++i ; in c++11! the above link says this – Koushik Shetty Apr 25 '13 at 12:03
2

This doesn't have anything to do with how printf and cout work. The C++ standard defines an ordering over the evaluation of expressions and their side effects. The wording changed a bit between C++03 and C++11, but it currently describes the evaluation of function arguments as being unsequenced. That is, you have no guarantee over the order in which a functions arguments will be executed.

Since you use the value of a and modify a in two expressions that are unsequenced, you have undefined behaviour.

If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324