Is it possible to rewrite the assignment statement to force C++ to evaluate the same as C# does?
Yes. To clarify, the rule in C# is that most of the time, the left side of an expression is evaluated fully before the right side. So C# guarantees that the evaluation of x
on the left of the +
happens before the side effect of the x = y
on the right side. C++ does not make this guarantee; compilers can disagree as to the meaning of this expression.
(Challenge: I said "most" for a reason. Give an example of a simple expression in C# where a side effect on the left is executed after a side effect on the right.)
I know this can be rewritten by splitting the assignments into two separate lines
Right. You wish to have a statement that has two side effects: increment y by the original value of x, and assign the original value of y to x. So you could write that as
int t = y;
y = y + x;
x = t;
But:
the goal is to maintain it in a single line.
I assume by "line" you mean "statement". Fine. Just use the comma operator.
int t = ((t = y), (y = y + x), (x = t));
Easy peasy. Why you would want to, I don't know. I assume this is a puzzle designed to elicit signal on whether or not you know about the comma operator.
Extra credit: How many of the parentheses in that statement are required?
Super bonus: what if we don't want to use the comma operator? We can use other operators as sequencing operators.
int t = ((t = y) & 0) || ((y = y + x) & 0) || (x = t);
We execute the left of the ||
, and it turns out to be false, so we execute the right side, and so on.
Similarly, ((expr1) & 0) ? 0 : (expr2)
guarantees you that expr1
runs before expr2
.
Basically what you need here is a guarantee that a number of subexpressions happen in a particular order. Look up "sequence points" to see which operators in C and C++ produce sequence points; you can use them to sequence expressions, hence the name.