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;
"
operator=" (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.