Arithmetic assignment operator - left side evaluated only once

半腔热情 提交于 2019-11-30 23:47:43
ouah

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.

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';
  printf("%c\n",value);
  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

however

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++.

Mohit Arora

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!