C says:
(C99, 6.5.16.2p3) "A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once."
Below are some examples of why it matters:
Example 1:
a[i++] += 1;
is the same as:
a[i] = a[i] + 1; i++;
because the left operand of +=
is evaluated once.
If it was not evaluated once it would be the same as:
a[i++] = a[i++] + 1;
which is of course different (and undefined behavior BTW).
Example 2:
*foo() += 1;
assuming foo
here returns a pointer to an object of a scalar type and produces side effects (for example it prints a string on the terminal). With the compound assignment operator it will print the string only once and not two times.
Example 3:
REG |= 0x01;
assuming REG
here is an IO register (something like #define REG (*(volatile uint8_t *) 0x42)
) and that every read to this specific IO register triggers a hardware event. The register will be read only once with the compound assignment operator and not two times.
EDIT: following @R. comment I striked the example 3. I think most compilers do not perform a read in this expression: REG = 31
or two reads with this expression: REG = REG | 0x01
.