

c - Arithmetic assignment operator - left side evaluated only once


As the title says I found such a sentence in some C lecture notes.

I can't invent any example proving that sentence.

In my opinion every of assignment operations is evaluated once, because when we want it to be evaluated more than once we put in in a loop. What am I missing then?

I've searched but couldn't find an answer here on SO.


C says:

(C99, "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.


Usually the += operator is introduced in the following way:

x += y;
x = x+y; // does the same

However, the note tries to tell you that this is in fact not accurate, as the left side of = and += might be any expression. As others have stated this can lead to undefined behaviour, but that's not the core of the issue.

For instance:

char* f() {
  static char value = 'a';
  return &value;

void g() {
  *f() = 'b'; // assigns 'b' which was 'a'
  *f() += 2; // changes 'b' to 'd'
  *f() = 'b';
  *f() = *f() + 2; // changes 'b' to 'd'

The difference is that f is executed twice in the last line, while it is executed once in the second.


Your question is very unclear and poorly worded, but I suspect what your note was in reference to is that the combined arithmetic+assignment operators allow you to do certain things without writing (and thus evaluating) the expression for the lvalue more than once. For instance,

*p++ += *q++;  /* p is incremented once, as desired */
*p++ = *p++ + *q++;  /* undefined behavior */

It especially matters when you'll be using these in macros, for instance:

#define ACCUM(d,s) (d)+=(s) /* good */
#define ACCUM(d,s) (d)=(d)+(s) /* dangerous */

Don't have anything to compile with handy but here is an interesting tidbit:

var1 += var++ would change the value of var1 to var1 + var


var1 += ++var would change the value of var1 to var1 + (var + 1)


There are some compound assignment operation in C. for e.g. +=,-=, *=,/=,%=

for e.g. i += 1 It increments the value of i by 1 like i++.


There are number of compound assignment operators. for eg. +=,-=,*=,/=,%=

as a+=b will give a=a+b for more details click on this