> Why is e1 evaluated only once in the compound assignment
> but in ordinary assignment e1 is evaluated twice if they are "completely same?"
Because they are not "completely same".
a = b + c ;
requires the right hand side
b + c
to be evaluated and the left hand side
a
to be evaluated.
Evaluation of
b + c
requires
b
to be evaluated and
c
to be evaluated.
a = a + c ;
requires the right hand side
a + c
to be evaluated and the left hand side
a
to be evaluated.
Evaluation of
a + c
requires
a
to be evaluated and
c
to be evaluated.
(
a
is evaluated twice, once for the right hand side and once for the left hand side.)
Even though
a = a + c ;
and
a += c ;
are not "completely same", if the observable behaviour of the program is indistinguishable with either construct, the implementation is allowed (by the "as-if" rule) to replace one construct with the other.
The "as-if" rule always applies; for scalars as well as for user-defined types.
An implementations is allowed to generate the same code for the three functions
foo()
,
bar()
and
foobar()
- because their observable behaviour is the same.
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 36 37 38 39 40 41
|
struct A
{
int i ;
A& operator+= ( int v ) { i += v ; return *this ; }
};
A operator+ ( A a, int v ) { a.i = a.i +v ; return a ; }
int foo( A a )
{
a += 6 ;
return a.i ;
/*
leal 6(%rdi), %eax
ret
*/
}
int bar( A a )
{
a = a + 6 ;
return a.i ;
/*
leal 6(%rdi), %eax
ret
*/
}
int foobar( A a )
{
A temporary_object = operator+( a, 6 ) ;
a.operator= (temporary_object) ;
return a.i ;
/*
leal 6(%rdi), %eax
ret
*/
}
|
http://coliru.stacked-crooked.com/a/fc30442ad5018c22