C steals a few neat things from Lisp
: "(almost!) anything is a value
Everybody who knows C knows that assignments are rvalues. Given appropriate types, you can say:
a = b = c;
" (the C++
term) is right associative
, so here's what it does:
- assigns the value of c to b.
- assigns the (new) value of b to a.
In C++, we can overload operator=; for a builtin type T it has the signature
T& operator=(T& a, S b);
By convention, operator=
returns its LHS by reference
So in C++ this is legal syntax!
(a = b) = c;
It's obviously not legal C: there, sanity
prevails and the result of an assignment is an rvalue, not
an lvalue. But C++ allows it; it means:
- Assign the value of b to a (using a.operator=(b) or operator=(a,b)).
This always has a side effect (the value of a changes), but since operator= is user-defined, it can have additional side effects (for an example see autoptr or almost any smart pointer).
In any case, (a=b) is an lvalue, so we can now...
- Assign the value of c to the lvalue (a=b), by convention to a.
So (assuming convention holds!) b
, like c
remains unchanged (indeed, b
needn't be an lvalue; it's not a reference
!), and a
changes its value twice
Another side effect of adding operator overloading to C, and trying to keep things orthogonal...
yaweh explains how to overcome this in your own classes. But for "
int a,b,c;", the code in the title works! Perhaps it's because having "&(a=4)" return a
const int* would be too much, even for C++-heads.