Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compound assignment E1 op= E2 is not equivalent to E1 = E1 op E2

cppreference says:

the behavior of every builtin compound-assignment expression E1 op= E2 (where E1 is a modifiable lvalue expression and E2 is an rvalue expression or a braced-init-list (since C++11)) is exactly the same as the behavior of the expression E1 = E1 op E2, except that the expression E1 is evaluated only once and that it behaves as a single operation with respect to indeterminately-sequenced function calls (e.g. in f(a += b, g()), the += is either not started at all or is completed as seen from inside g())."

I want to know if this explanation is wrong (insufficient) or I'm understanding something incorrectly.

I understand there's inherent difference between E1 = E1 + E2 and E1 += E2, which is explained here:

#include<iostream>
int main() {

    int x;

    x = 1;
    x += (-1) ? 2 : 2; 
    std::cout << x << std::endl; //prints 3

    x = 1;
    x = x + (-1) ? 2 : 2;
    std::cout << x << std::endl; //prints 2

    x = 2;
    x += (-2) == 0;
    std::cout << x << std::endl; //prints 2

    x = 2;
    x = x + (-2) == 0; // prints 1

}

My guess is E1 op= E2 has the following behavior:

  • Evaluate E1 and E2 (unsure about the order) and assign result of operation between two evaluation to E1, which is (E1) = (E1) op (E2).

So would a better explanation for compound assignment operation's behavior be (E1) = (E1) op (E2)? (or E1 = E1 op (E2), because E1 only can have operator of higher precedence than assignment operator and lower precedence than op operator, without parentheses, if E1 op (E2) wants to produce different result from (E1) op (E2). Such operator whose result is a modifiable lvalue doesn't exist.)

like image 728
Pleasure Avatar asked Jul 21 '26 19:07

Pleasure


1 Answers

That quote from cppreference comes directly from the C++ Standard:

[expr.ass]/6

The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
Such expressions are deprecated if E1 has volatile-qualified type; see [depr.volatile.type].
For += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type.
In all other cases, E1 shall have arithmetic type.

In this context, the term expression has already been defined and E1 op= E2 being equivalent to E1 = E1 op E2 clearly doesn't mean the expressions are equivalent in their textual representation, but in their resolution (type, value and side-effects).

[A] better explanation for compound assignment operation's behavior could be (E1) = (E1) op (E2)?

I only can express my opinion: I think the cpprederence page is right to quote the Standard here, but a note could be added to make sure readers do not get it wrong.

like image 183
YSC Avatar answered Jul 23 '26 08:07

YSC