1

I read from the book K&R an example of precedence:

x = f() + g();

f may be evaluated before g or vice versa

What I know is that the order of evaluation of paraentheses () is higher than the + and after that comes the = . Besides for the () the order of evaluation will be from left to right. So if I am right why did he say may be evaluated as if it is not certain ?

The question is a little bit silly but very important for me to clear the unclear.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 1
    There's no sequence points between `f()` and `g()`, so the compiler can do what it likes. Expressions in C, as a general rule, are *not* evaluated left-to-right. – sapi Jan 02 '15 at 23:40
  • 2
    See also [In C99, is `f()+g()` undefined or merely unspecified?](http://stackoverflow.com/questions/3951017/in-c99-is-fg-undefined-or-merely-unspecified/3951189#3951189) – Jonathan Leffler Jan 02 '15 at 23:52
  • 2
    For the binary operators, the 'left to right' note in the table of precedences means that `a - b - c` has to be interpreted as `(a - b) - c` rather than as `a - (b - c)`. It also means that `a + b - c` is interpreted as `(a + b) - c` rather than `a + (b - c)`. However, that doesn't stop `c` being evaluated before either `a` or `b`; the order in which the operands are evaluated is still up to the compiler. – Jonathan Leffler Jan 02 '15 at 23:58
  • Thanks I just found it ! :D – Meninx - メネンックス Jan 02 '15 at 23:59
  • last question : after understanding the problem stated above is it similar to this one, I mean if we changed the operator and the variable to get this statement: `x=(a,b)` Is it left to the compiler to evaluate `a` first or `b` first or do we have a known sequence of evaluation @JonathanLeffler ? – Meninx - メネンックス Jan 03 '15 at 00:24
  • 2
    In the context shown (`x=(a,b)`), you have a comma operator. The comma operator is defined to evaluate its LHS (`a`) completely, then there's a sequence point, and then it evaluates its RHS (`b`) completely, and assigns that to `a`. Now, `a` could be evaluated before either `b` or `c`, or after both `b` and `c`; in theory, it could probably be evaluated elsewhere in the expression too, but it is pretty unlikely that the compiler would do that. However, all of `b` is evaluated before anything of `c` is evaluated. – Jonathan Leffler Jan 03 '15 at 00:29
  • great **sequence point** this what I was looking for ! BIG Thanks @JonathanLeffler ! :) – Meninx - メネンックス Jan 03 '15 at 00:39

2 Answers2

4

They mean that it is up to the C compiler implementation whether to evaluate the left side of the + first over the right side, or vice versa before applying the + operator to those results. This is important if f() and g() perform what are called side effects. If f() modifies some global variable, and g() modifies the same global variable, the modification performed by f() will prevail if the C compiler evaluates right-to-left, while the modification performed by g() will prevail if the compiler evaluates left-to-right.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Danny Daglas
  • 1,501
  • 1
  • 9
  • 9
  • 2
    It is worth noting that the compiler doesn't have to treat the same expression the same way each time it encounters it; it may choose to compile the code differently depending on surrounding context. New runs of the same compiler, or new versions of the compiler, or different compilers -- all of those may also give different results. While most compilers are in fact deterministic, they're not obliged to be as long as they follow the 'as if' rule. – Jonathan Leffler Jan 02 '15 at 23:55
0

What is confusing is that the standard says that + associates left-to-right, but this does not means that each sub expression of a sum is evaluated from left to right! Order of evaluation of sub-expressions is not specified. Thus if you have:

f() + g() + h()

then the compiler is free to generate something like:

t1 = h()
t2 = f()
t3 = g()
(t2+t3)+t1

It is the same problem for expressions like i++ + ++i for which many programmers fail about.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69