Q: Can I use explicit parentheses to force the order of evaluation I want, and control these side effects? Even if I don't, doesn't precedence dictate it?
A: Not in general.
Operator precedence and explicit parentheses impose only a partial ordering on the evaluation of an expression. In the expression
f() + g() * h()although we know that the multiplication will happen before the addition, there is no telling which of the three functions will be called first. In other words, precedence only partially specifies order of evaluation, where ``partially'' emphatically does not cover evaluation of operands.
Parentheses tell the compiler which operands go with which operators; they do not force the compiler to evaluate everything within the parentheses first. Adding explicit parentheses to the above expression to make it
f() + (g() * h())would make no difference in the order of the function calls. Similarly, adding explicit parentheses to the expression from question 3.2 to make it
(i++) * (i++) /* WRONG */accomplishes nothing (since ++ already has higher precedence than *); the expression remains undefined with or without them.
When you need to ensure the order of subexpression evaluation, you may need to use explicit temporary variables and separate statements.
References:
K&R1 Sec. 2.12 p. 49, Sec. A.7 p. 185
K&R2 Sec. 2.12 pp. 52-3, Sec. A.7 p. 200