Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

i = i++; is undefined. Is i = foo(i++) also undefined?

For example:

int foo(int i) { return i; }

int main()
{
  int i = 0;

  i = i++;      // Undefined
  i = foo(i++); // ?

  return 0;
}

What would the current ISO C++ standard specify for this case?

EDIT:

Here's where I get confused:

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

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, and they are not potentially concurrent (1.10), the behavior is undefined.

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression

Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

So it seems you could have a value computation on the left side of the assignment (just i), and a side effect on the right side (the modification of i from i++) which aren't sequenced with respect to each other.

EDIT2:

For anyone who finds themselves here, there is a really great explanation about sequencing that I found here.

like image 889
JustinBlaber Avatar asked Jun 26 '15 01:06

JustinBlaber


Video Answer


2 Answers

The last sentence in your quote says "that is not otherwise specifically sequenced before or after the execution of the body of the called function" so the question is whether the increment and the assignment are "otherwise specifically sequenced before or after" the function body.

1.9 [intro.execution] p15 has the answer:

When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note ]

So the increment of i happens before the function body, and the assignment to i happens after the function returns, so it is perfectly well-defined.

In pre-C++11 terminology, the function call introduces a sequence point between the increment and the assignment.

like image 190
Jonathan Wakely Avatar answered Oct 17 '22 17:10

Jonathan Wakely


i = foo(i++); is fine, because i++ is executed before foo() is called. A copy of i is made, i is then incremented, then the copy is passed to foo(). It is the same as doing this explicitly:

int tmp = i++;
i = foo(tmp);
like image 26
Remy Lebeau Avatar answered Oct 17 '22 18:10

Remy Lebeau