Compound assignment

Question. Is:

value *= expression

always equivalent to

value = value * expression

where value is any int or double, expression is any expression involving standard ints and doubles; no objects or overloading of operators etc.
Last edited on
Yes.
More votes, please.
In value *= expression, value is evaluated only once.

In value = value * expression, value is evaluated twice.

Other than that, the two are equivalent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

int cnt = 0 ;

int& value()
{
    static int i = 0 ;
    std::cout << ++cnt << ". evaluate value()  " ;
    return i ;
}

int main()
{
    int expression = 25 ;

    cnt = 0 ;
    std::cout << "value() *= expression ;\n" ;
    value() *= expression ; // 1. evaluate value()

    std::cout << "\n\n-----------------\n" ;

    cnt = 0 ;
    std::cout << "value() = value() * 25 ;\n" ;
    value() = value() * 25 ; // 1. evaluate value()  2. evaluate value()

    std::cout << "\n\n-----------------\n" ;

    {
        int value = 0 ;

        ++value *= expression ;

        ++value = ++value * 25 ; // undefined behaviour before C++17
    }
}

http://coliru.stacked-crooked.com/a/5e7dd60a9461d1d8
'expression' can be a complicated expression, not just a single value, @JLBorges

This is getting more interesting, though. More participants please ...
More votes, please.

Election day was yesterday and many want to get a long rest from voting.

Why don't you accept JLBorges' answer? I doubt you will get better one,

What additional info are you looking for?
So which of the rules of the game does this example break, then?
1
2
3
4
5
6
7
8
9
#include<iostream>
using namespace std;

int main()
{
   int value;
   value = 2;   value = value * 2 / 3;     cout << value << endl;
   value = 2;   value     *=    2 / 3;     cout << value << endl;
}
Neither breaks any rules, though the meaning and effect of the two expressions are different.

value = value * 2 / 3 ; is parsed as value = ( value * 2 ) / 3 ;
(multiplicative operators *, /, and % group left-to-right.)

value *= 2 / 3 ; is parsed as value *= ( 2 / 3 ) ; ie. value *= 0 ;
Order of evaluation is different. Operators * and / have the same priority, so neither takes precedence.

 
value * 2 / 3
is evaluated from left to right, as
 
(value * 2) / 3


value *= 2 / 3; would evaluate (2 / 3) first (with integer division playing a significant role here).
I'm well aware why the answers are what they are; (the consequences of integer division - deliberately chosen for this example). It wasn't meant as a frivolous post, and I wasn't off my head when conjuring it up!

I'm posting this as a salutary warning that you can't simply substitute
value *=
for
value = value *

... and because I managed to fall victim to it myself three times in an hour when I decided to "tidy up" some code previously written in a different programming language.

I hope doug4 will forgive me!
Last edited on
value = value * 2 / 3; is not of the form value = value * expression because 2 / 3 is not an expression in this context.
Last edited on
Topic archived. No new replies allowed.