0
#include<stdio.h>
int main()
{
    int i=2;
    printf("%d %d \n",++i,++i);
}

The above code gives an output 4 4. Can any one help how to explain the output?

unwind
  • 391,730
  • 64
  • 469
  • 606
Raj
  • 447
  • 6
  • 11
  • 1
    This is undefined behavior. See for example here http://stackoverflow.com/questions/19694756/how-pre-and-postfix-are-evaluated-in-printf – jaap Nov 01 '13 at 10:36

3 Answers3

2

++i is a prefix increment. Printf should first evaluate its arguments before printing them (although in which order, is not guaranteed and, strictly speaking, undefined - See Wiki entry on Undefined Behavior: http://en.wikipedia.org/wiki/Undefined_behavior ).

The prefix increment is called "increment and fetch", i.e. it first increments the value and then gives it to the caller.

In your case, i was first incremented twice, and only afterwards the output was formatted and sent to the console.

Ashalynd
  • 12,363
  • 2
  • 34
  • 37
  • How did this answer get a vote? `in func(a,a++) , is not comma operator, its merely a separator between the arguments a and a++. The behaviour is undefined in that case if a is considered to be a primitive type) ` – Sadique Nov 01 '13 at 10:43
  • @Acme I voted it up, it doesn't mention the comma operator at all? But it does mention the fact that this is simply a function call, and that calls need to evaluate all their arguments before doing the actual call, which seems to the the point that is confusing the OP. – unwind Nov 01 '13 at 10:45
  • @unwind - There is a subtle difference in what you are saying and in the answer. The answer is talking about order of evaluation being unspecified which is correct, but it does not mention it to be UB . This `In your case, i was first incremented twice, and only afterwards the output was formatted and sent to the console.` is not correct. This `printf("%d %d \n",++i,++i);` is clear cut UB. What will be evaluated first this `"%d %d \n"`, this `++i` or this `++i` - think about it. – Sadique Nov 01 '13 at 10:51
  • @Acme what is not correct? Do you meant that printf could start formatting before evaluating what's getting into the formatted string? – Ashalynd Nov 01 '13 at 10:52
  • Reasoning out Undefined Behavior.@Ashalynd – Sadique Nov 01 '13 at 10:53
  • @Acme: that's true, I should have been more critical. Can't undo my +1 now, though. :| – unwind Nov 01 '13 at 10:55
  • @Acme it is indeed UB. I should have mentioned that term I guess. – Ashalynd Nov 01 '13 at 10:56
  • @unwind - Both the answers have made the same mistake. – Sadique Nov 01 '13 at 10:56
1

It has to do with sequence points and it can result in undefined behavior.

Straight from Wikipedia:

Before a function is entered in a function call. The order in which the arguments are evaluated is not specified, but this sequence point means that all of their side effects are complete before the function is entered.

More info here: http://en.wikipedia.org/wiki/Sequence_point

Zoli
  • 1,137
  • 7
  • 12
0

Both the answers have made the same mistake. Its clear cut UB and not just unspecified behavior.

What you have experienced is Undefined behavior. Please read about sequence points. Comma is a separator in function calls not an operator.

A sequence point is a point in time at which the dust has settled and all side effects which have been seen so far are guaranteed to be complete. The sequence points listed in the C standard are:

at the end of the evaluation of a full expression (a full expression is an expression statement, or any other expression which is not a subexpression within any larger expression); at the ||, &&, ?:, and comma operators; and at a function call (after the evaluation of all the arguments, and just before the actual call).

The Standard states that

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.

What will be evaluated first this "%d %d \n", this ++i or this ++i (second one) - think about it. This would be unspecified behavior:

void f(int x)
{
    printf("%d ",x);
}
int main()
{
    int i=0;
    f(i++) ;
}

From wiki:

Before a function is entered in a function call. The order in which the arguments are evaluated is not specified, but this sequence point means that all of their side effects are complete before the function is entered. In the expression f(i++) + g(j++) + h(k++), f is called with a parameter of the original value of i, but i is incremented before entering the body of f. Similarly, j and k are updated before entering g and h respectively. However, it is not specified in which order f(), g(), h() are executed, nor in which order i, j, k are incremented. Variables j and k in the body of f may or may not have been already incremented. Note that a function call f(a,b,c) is not a use of the comma operator and the order of evaluation for a, b, and c is unspecified.

Sadique
  • 22,572
  • 7
  • 65
  • 91