The bitwise binary operators, &
, |
and ^
, are
associative. The arithmetic binary operators +
and *
are associative if the operand type is unsigned. An associative
binary operator, when used repeatedly, can combine any number of
operands. The operands’ values may be computed in any order, and
since the operation is associative, they can be combined in any order
too.
Thus, given four functions that return unsigned int
, calling
them and adding their results as here
(foo () + bar ()) + (baz () + quux ())
may add up the results in any order.
By contrast, arithmetic on signed integers is not always associative
because there is the possibility of overflow (see Integer Overflow). Thus, the additions must be done in the order specified,
obeying parentheses (or left-association in the absence of
parentheses). That means computing (foo () + bar ())
and
(baz () + quux ())
first (in either order), then adding the
two.
The same applies to arithmetic on floating-point values, since that too is not really associative. However, the GCC option -funsafe-math-optimizations allows the compiler to change the order of calculation when an associative operation (associative in exact mathematics) combines several operands. The option takes effect when compiling a module (see Compilation). Changing the order of association can enable GCC to optiimize the floating-point ooerations better.
In all these examples, the four function calls can be done in any order. There is no right or wrong about that.