The description of the first is the correct description for the second. The correct description of the first is very similar, you just need a "copy current value of m1" step added before the others.
But you do have a distinct lack of sequence points here, if m1
has a primitive type. The rules change somewhat between C++03 and C++11.
If m1
has a user-defined type, then there are function calls involved which influence sequencing.
This code
offSpring1[m1++] = temp1;
performs the following (if m1
is a primitive type):
auto const old_m1(m1);
auto const new_m1(old_m1 + 1);
auto& lhs(offSpring[old_m1]);
parallel { lhs = temp1; m1 = new_m1; }
This code
offSpring1[++m1] = temp1;
is exactly the same except that lhs
is bound using new_m1
instead of old_m1
.
In either case, it is unspecified whether lhs
is written to before or after m1
.
If m1
is not a primitive type, it looks more like:
auto const& index = m1.operator++(0); // one argument
auto& lhs = offSpring.operator[](index);
lhs = temp1;
vs
auto const& index = m1.operator++(); // no arguments
auto& lhs = offSpring.operator[](index);
lhs = temp1;
In both these cases, the change to m1
is definitely made before the write to lhs
.