anime
anime

Reputation: 118

What should be the output of the following and why it should depend on compiler?

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;
}

Upvotes: 1

Views: 106

Answers (2)

user2736738
user2736738

Reputation: 30936

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

Upvotes: 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).

Upvotes: 3

Related Questions