In the expression (i / 2) + func(&i)
, the compiler (or the C implementation generally) is free to evaluate either i / 2
first or func(&i)
first. Similarly, in func(&j) + (j/2)
, the compiler is free to evaluate func(&j)
or j/2
first.
Precedence is irrelevant. Precedence tells us how an expression is structured, but it does not fully determine the order in which it is evaluated. Precedence tells us that, in a * b + c * d
, the structure must be (a * b) + (c * d)
. In a + b + c
, precedence, in the form of left-to-right association for +
, tells us the structure must be (a + b) + c
. It does not tell that a
must be evaluated before c
. For example, in a() + b() + c()
, the structure is (a() + b()) + c()
, but the compiler may call the functions in any order, holding their results in temporary registers if needed, and then add the results.
In func(&j)+(j/2)
, there is no right-to-left precedence or association. No rule in the C standard says j/2
must be evaluated before func(&j)
.
A compiler might tend to evaluate subexpressions from left to right, in the absence of other constraints. However, various factors may alter that. For example, if one subexpression appears multiple times, the compiler might evaluate it early and retain its value for reuse. Essentially, the compiler builds a tree structure describing the expressions it needs to evaluate and then seeks optimal ways to evaluate them. It does not necessarily proceed left to right, and you cannot rely on any particular evaluation order.
Questions about Sequencing
The C standard has a rule, in C 2018 6.5 2, that says if a modification to an object, as occurs to i
in the statement *k+=4;
, is unsequenced relative to a value computation using the same object, as occurs for i
in i / 2
, then the behavior is undefined. However, this problem does not occur in this code because the modification and the value computation are indeterminately sequenced, not unsequenced: 6.5.2.2 10 says “… 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 execution of the called function.” C 5.1.2.3 3 says “… Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which…”