1

Please help me to understand the output.Here we know, we can't say that f1() is evaluated before f2() due to Left to Right associativity of '+' because associativity only happens when there are 2 or more than 2 operators of the same precedence.So what should be the concept used to determine the answer?

// Associativity is not used in the below program.
int x = 0; 
int f1() {
  x = 5;
  return x;
} 
int f2() {
  x = 10;
  return x;
}
int main() {
  int p = f1() + f2();
  printf("%d ", x);
  return 0;
}
anime
  • 118
  • 10

2 Answers2

3

Because the standard doesn't impose any constraint in it.

The section that says this is from 6.5

The grouping of operators and operands is indicated by the syntax.85) Except as specified later, side effects and value computations of subexpressions are unsequenced.

From standard itself 6.5.2.2 (Showing an example that standard doesn't impose any constraint)

In the function call

  (*pf[f1()]) (f2(), f3() + f4())

the functions f1, f2, f3, and f4 may be called in any order. All side effects have to be completed before the function pointed to by pf[f1()] is called.

The answer to your question would be unspecified. You can't say something for sure. If f1() is called first result would be something and if it is other way round then the result would be different.

To support what I said check this link

... 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. If the body of f accesses the variables j and k, it might find both, neither, or just one of them to have been incremented. (The function call f(a,b,c) is not a use of the comma operator; the order of evaluation for a, b, and c is unspecified.)

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • Can you please explain it with a short example? – anime Dec 25 '17 at 15:52
  • "All side effects have to be completed before the function pointed to by pf[f1()] is called."--I can't understand this. – anime Dec 25 '17 at 15:52
  • @anime.: Well the empasis is what of importance in this context. The order of the function calls is not specified rather it is constrained that any side effect (variable modification etc) be completed before it goes to call the function pointed by function pointer `pf`. – user2736738 Dec 25 '17 at 15:55
  • Re: “The answer to your question would be implementation defined.” Where does the C standard say this is implementation defined? There is a difference between things the C standard says an implementation must define and things the C standard does not impose requirements on. An implementation might order the evaluation differently at different times and/or never define what order it will use. – Eric Postpischil Dec 25 '17 at 16:26
  • @EricPostpischil.: I guess the correct word would be `unspecified`? Standard is like you said at times a bit trickier to decipher. Will be glad if you can specify the correct wordings? – user2736738 Dec 25 '17 at 16:28
3

These two function calls are indeterminately sequenced w.r.t. each other. C11 6.5.2.2p10:

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.

And indeterminately sequenced means that C11 5.1.2.3p3

Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which

Therefore either f1 or f2 will be called first, and the execution of the functions would not be interleaved. You can tell it afterwards by checking the value of x - if it is 5 then f2 was called first; if 10, f1 was called first.

The footnote 86 says also:

In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations.

I.e. if you did this in a loop, on first iteration f1 might be called first and on next f2 might be called first...


The operator associativity and precedence have almost nothing at all to do with actual order of evaluation - the order of evaluation of operands of +, like almost all other operators, is unspecified - and unsequenced (C11 6.5p3).