I = я ++; undefined. Является ли я = foo (i ++) также undefined?

Например:

int foo(int i) { return i; }

int main()
{
  int i = 0;

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

  return 0;
}

Что бы определить текущий стандарт ISO С++ для этого случая?

EDIT:

Здесь, где я запутался:

За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не подвержены.

Если побочный эффект скаляра объект не влияет на какой-либо другой побочный эффект на один и тот же скалярный объект или вычисление значения используя значение одного и того же скалярного объекта, и они не являются потенциально параллельными (1.10), поведение undefined.

Во всех случаях назначение упорядочивается после значения вычисление правого и левого операндов и перед вычислением значения выражения присваивания

Каждая оценка в вызывающей функции (включая другие вызовы функций), которая иначе не является секвенированные до или после выполнения тела вызываемой функции, неопределенно секвенированы с в отношении выполнения вызываемой функции.

Итак, кажется, что вы можете вычислить значение в левой части задания (просто i) и побочный эффект с правой стороны (модификация i from i++), которые не являются упорядоченные относительно друг друга.

EDIT2:

Для тех, кто оказался здесь, есть действительно отличное объяснение о последовательности, которую я нашел здесь.

Ответы

Ответ 1

Последнее предложение в вашей цитате говорит ", которое иначе не было секвентировано до или после выполнения тела вызываемой функции, поэтому вопрос заключается в том, является ли приращение и присвоение" иначе "специально секвенированные до или после" тела функции".

1.9 [intro.execution] p15 имеет ответ:

При вызове функции (независимо от того, является ли функция встроенной), каждое вычисление значения и побочный эффект, связанное с любым выражением аргумента, или с выражением postfix, обозначающим вызываемую функцию, является секвенированы перед выполнением каждого выражения или выражения в теле вызываемой функции. [Примечание: значение вычисления и побочные эффекты, связанные с разными выражениями аргументов, не имеют никакого значения. - конечная нота]

Таким образом, приращение i происходит перед телом функции, а назначение i происходит после возвращения функции, поэтому оно отлично определено.

В терминологии pre-С++ 11 вызов функции вводит точку последовательности между приращением и присваиванием.

Ответ 2

i = foo(i++); отлично, потому что i++ выполняется до вызова foo(). Выполняется копия i, затем увеличивается i, затем копия передается в foo(). Это то же самое, что делать это явно:

int tmp = i++;
i = foo(tmp);