[Solved] Implications of operator precedence in C


Although those examples come from a different language, I think they are the same as operator precedence in C. In general, you’d be better off using a reference for the C language, such as the C standard, or a summary such as the one in Wikipedia.

However, I don’t believe that is actually what you are asking. Operator precedence has no implications for order of evaluation. All operator precedence does is show you how to parenthesize the expression. A C compiler is allowed to evaluate the operations in just about any order it wishes to. It is also allowed to use algebraic identities if it is provable that they will have the same result for all valid inputs (this is not usually the case for floating point calculations, but it is usually true for unsigned integer calculations).

The only cases where the compiler is required to produce code with a specific evaluation order are:

  1. Short-circuit boolean operators && and ||: the left argument must be evaluated first, and in some cases the right argument may not be evaluated;

  2. The so-called ternary operator ?:: the left argument (before the ?) must be evaluated first; subsequently, exactly one of the other two operators will be evaluated. Note that this operator groups to the right, demonstrating that there is no relationship between grouping and evaluation order. That is, pred_1 ? action_1() : pred_2 ? action_2() : pred_3 ? action_3() is the same as pred_1 ? action_1() : (pred_2 ? action_2() : pred_3 ? action_3()), but it’s pred_1 which must be evaluated first.

  3. The comma operator ,: the left argument must be evaluated first. This is not the same as the use of the comma in function calls.

  4. Function arguments must be evaluated before the function is called, although the order of evaluation of the arguments is not specified, and neither is the order of evaluation of the expression which produces the function.

The last phrase refers to examples such as this:

// This code has Undefined Behaviour. DO NOT USE
typedef void(*takes_int_returns_void)(int);
takes_int_returns_void fvector[3] = {...}
//...
//...
(*fvector[i++])(i);

Here, a compiler may choose to increment i before or after it evaluates the argument to the function (or other less pleasant possibilities), so you don’t actually know what value the function will be called with.

In the case of 1+2*2*4, the compiler must generate code which will produce 17. How it does that is completely up to the compiler. Furthermore, if all x, y and z are all unsigned integers, a compiler may compile 1 + x*y*z with any order of multiplications it wants to, even reordering to y*(x*z).

7

solved Implications of operator precedence in C