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);