10

#include<stdio.h>
main()
{
    int a=10;
    printf("\n %d %d", a, a++); //11 10
    a=10;
    printf("\n %d %d", a++, a); //10 11
    a=10;
    printf("\n %d %d %d ", a, a++,++a); //12 11 12
}

after running this I got the output given in comments. as far as I know first output is expected because execution of printf goes from right to left but could not understand second and third

shrikant
  • 101
  • 1
  • 1
  • 3
  • +1 for good question.. I was not aware it worked in that way – Earlz Feb 23 '10 at 16:05
  • The calculation of the arguments to *printf* is not part of the execution of *printf*. The arguments must all be calculated before *printf* starts executing. – David Schwartz Aug 27 '11 at 17:04

5 Answers5

9

Nothing goes "from right to left" in function argument evaluation. When function arguments are evaluated, the order of evaluation is unspecified and there are no sequence points between evaluating separate arguments. This means that there's absolutely no temporal ordering in this process. The arguments can be evaluated in any order, and the process of their evaluation can be intertwined in any way.

However, your code suffers from even worse problems. All three statements that call printf produce undefined behavior (UB) because they either make an attempt to modify the same object (a) twice without a sequence point between the modifications (the third call), or they attempt to modify an object and read it for an independent purpose (the first and the second call). So, it is too early to even mention the order of evaluation. Your code's behavior is undefined.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

None of the outputs can really qualify as unexpected. All the arguments to a function are evaluated before entry to the function itself -- but the order of their evaluation relative to each other is unspecified, so all of these results are allowed. Officially, your last one (that has two separate instances of incrementing a) has undefined behavior, so it doesn't have to do anything sensible at all.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • If there is a sequence point between evaluating each argument, why should the last one in particular be more wrong than the others? – UncleBens Feb 23 '10 at 16:09
  • The last one is "more wrong" because it modifies `a` twice without an intervening sequence point. The rest only modify `a` once. – Jerry Coffin Feb 23 '10 at 16:11
  • @UncleBens: there isn't a sequence point between evaluating each argument. There is a sequence call after the operands have been evaluated and before the function is called, but there are no sequence points (in the exmple) while the arguments are being evaluated. – Jonathan Leffler Feb 23 '10 at 16:12
  • @Jerry: I think that even the calls with a single increment applied to 'a' are undefined behaviour too - not just the one with two increments applied. – Jonathan Leffler Feb 23 '10 at 16:13
  • @Johathon: That's open to some argument. The exact wording from the standard (§6.5/2) is: "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 read only to determine the value to be stored." I've seen (and participated in) several arguments on comp.std.c about whether that makes (code like) the others UB or not. In the end, nobody seems quite sure, but nobody can come up with wording that would make it clear either. – Jerry Coffin Feb 23 '10 at 16:20
  • Well, g++ says for `printf("%d %d", a, ++a);` that the operation on a "may be" undefined - not unspecified. (That's in C++ mode, but would the languages really differ here?!) – UncleBens Feb 23 '10 at 17:18
  • @UncleBens: That message sounds pretty accurate. The last one is clearly UB; the others might be, depending on interpretation. – Jerry Coffin Feb 23 '10 at 17:59
3

++a means increment a first, and then return evaluate the expression. (a changes, and the expression evaluates as a + 1)

a++ means evaluate a (so, erm, a), and then increment it. So a is passed, but the value of a is then (ie afterwards) changed to a+1.

Martin Milan
  • 6,346
  • 2
  • 32
  • 44
  • Though the other people saying that there is no set order of evaluation are also correct - I've just tried to explain the postfix and prefix operators... – Martin Milan Feb 23 '10 at 16:13
2

You are invoking undefined behaviour by referencing both 'a' and 'a++' in the argument list.

It is not defined which order the arguments are evaluated in. Different compilers may choose different orders. A single compiler can choose different orders at different times.

Do not do it!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

Function parameters are not evaluated in a defined order in C. Therefore one cannot tell beforehand if a or a++ will be evaluated first when calling printf.

See Parameter evaluation order before a function calling in C

Community
  • 1
  • 1
Hans W
  • 3,851
  • 1
  • 22
  • 21