Calling f(a,a) in the following code is undefined behavior?
#include <iostream>
int f(int &m, int &n) {
m++;
n++;
return m + n;
}
int main() {
int a = 1;
int b = f(a, a);
}
There is no undefined behavior with respect to modifying m and n since the modifications of both variables are sequenced. The modification of m will happen before the modification of n since they are both full expressions and all side effects of a full expression are sequenced before the side effects of the next full expression.
The relevant section of the draft C++ standard is section 1.9 Program execution which says:
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.8.
and:
If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined
on the other hand the following:
m++ + n++ ;
is undefined behavior since the the order of evaluation of each sub expression is indeterminately sequence with respect to each other.
Jonathan brings up the issue of strict aliasing but I don't see how the compiler can assume that n and m are not aliasing each other and my experiments on godbolt does not indicate any unexpected aliasing assumptions.
Note, a full expression is:
[...]an expression that is not a subexpression of another expression[...]
Usually the ; denotes the end of a full expression.
return ++m + ++n;would be.