bladder: You're actually on to something there, I didn't think of that. But I'm not so sure if you're actually right in the way that the swap expression is undefined. The standard clearly says that such an expression can be undefined, but that is more in the general sense. The real question we need answered here is: is a compiler really allowed *in this particular case* to use old values of a and/or b high in the expression tree.
Surely, this is not undefined, at least not according to that paragraph:
a += b += 3;
both b and a are changed only once in the expression. Yet, how is that different when changing a to b. so it reads b += b += 3? If the compiler can choose the old value of b on the right side of the first +=, the first example would be undefined as well, which isn't the case.
But, when rambling about this, something came up. It may very well have to do with the actual
storage of the result in the variables. So suppose we have this code
int b = 1;
b += b += 2;
Of course, you'd expect b to be increased to 3, and then add the result (3) to the new value of b (3), which results in 6.
Now let's assume some intermediate code the compiler produces with this expression
int b = 1;
register reg_b = b + 2;
b = reg_b; // #1
register reg_b2 = reg_b + reg_b;
b = reg_b2; // #2
Now, almost every compiler would ignore #1 here, but the standard doesn't say that it has to, nor does it say that it should come before #2. Clearly, when #1 is generated after #2, b would finally yield 3 instead of the 6 you suspect. I think this is where the 'undefinedness' (is that a word? it is now) comes from.
So yeah, that swap expression is probably undefined. Not in the way that it calculates the wrong value, but in the way that the actual calculated value is not returned to the variables correctly
I was wrong, every point their finger at me

COMMENCE FINGER-POINTING