1

can anyone please help me understand the output of code below:

int main()
{
    int a=35;
    printf("%d %d %d %d %d",a--,a,a=20,a++,a=39);
    return 0;
}

output:20 19 19 39 19

appreciated insight on how assignment is handled(compiled) in c in printf function.

ss_t
  • 31
  • 1
  • 3
  • 6
    This is a dupe of about a million and half things... hang on a sec while I find one of them... – Mysticial Jul 31 '12 at 09:06
  • 4
    See http://stackoverflow.com/questions/3575350/sequence-points-in-c ... the main thing to understand is that your code has undefined behavior and this is not valid C code. – Jim Balter Jul 31 '12 at 09:07

2 Answers2

7

This is unspecified behavior. The order of evaluation of function arguments is not specified in the C standard, and therefore it could happen in any order.

People have already given you some links in the comments you can read on. But in short, there are things called "sequence points". These ensure that everything that needed to be executed before, is executed, and then the program can continue. Between two sequence points, the instructions can execute in any order.

From the C11 standard:

3.4.4:

  1. unspecified behavior
    use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance

  2. EXAMPLE An example of unspecified behavior is the order in which the arguments to a function are evaluated.

6.5.2.2.10 says

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.

In other words, there is no sequence point between the evaluation of a function's arguments, therefore they may be evaluated in whichever order the compiler feels like.

To complete the answer, this is also undefined behavior, as you try to change the value of a multiple times between two sequence points.

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.84)

84) his paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • 1
    It's undefined behavior, which is a defined term in the C standard. There are other things that are unspecified but are not undefined, such as implementation-defined behavior. – Jim Balter Jul 31 '12 at 09:15
  • 1
    @JimBalter, C11 disagrees with you, see my update – Shahbaz Jul 31 '12 at 09:22
  • 1
    First, that language is new in C11. Second, the OP's code changes the value of `a` in ways that constitute *undefined* behavior because there's no sequence point; the lack of specification of evaluation of the order of arguments is just gravy. So the C11 standard does not contradict anything in my statement. – Jim Balter Jul 31 '12 at 09:34
  • To clarify: Even if the order of evaluation of arguments were defined to be left to right, the value of the `a` and `a++` arguments would be undefined. – Jim Balter Jul 31 '12 at 09:38
  • 1
    @jimbalter, you are right, it is also undefined behavior – Shahbaz Jul 31 '12 at 09:38
0
printf("%d %d %d %d %d",a--,a,a=20,a++,a=39);

This is undefined behavior.

That means the program can print: 20 19 19 39 19 or 0 0 0 0 0 or even format your hard drive.

(C99, 6.5p2) "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.

And of course a violation of a "shall" that is not a constraint means the prgram invokes undefined behavior (see 4.p2 in C99).

ouah
  • 142,963
  • 15
  • 272
  • 331
  • The program "can" format your hard drive in the sense that the C standard does not impose any behavioral requirement on the implementation in the case of code that has undefined behavior -- such code falls outside the scope of the standard. However, as the C99 Rationale states: "The goal of adopting this categorization is to allow a certain variety among implementations which permits quality of implementation to be an active force in the marketplace ...". Any implementation that formatted your hard drive in this case would fail in the marketplace. – Jim Balter Jul 31 '12 at 09:51
  • @JimBalter the undefined behavior can format your hard drive disregarding the implementation. If we take another example of undefined behavior: a buffer overflow (most of them are usually UB from C rules), an attacker could exploit the buffer overflow and injects some shellcode than could deliberately format your hard drive. – ouah Jul 31 '12 at 09:59
  • "the undefined behavior can format your hard drive disregarding the implementation" -- Yes, I explicitly said it can (well not disregarding the implementation ... there is nothing *but* implementation, which is unconstrained by the standard). " If we take another example of undefined behavior" -- I explicitly referred to "this case". Please don't waste your or my time attacking strawmen rather than what I actually wrote. Thanks. – Jim Balter Jul 31 '12 at 10:12