Я прочитал "C++. Primer plus. Stephen Prata" (6-е издание). На странице 209 было:
y = (4 + x++) + (6 + x++);
Выражение
4 + x++
не является полным выражением, поэтому C++ не гарантирует, чтоx
будет увеличено сразу после вычисления подвыражения4 + x++
. Здесь полное выражение представляет собой весь оператор присваивания, а точка с запятой отмечает точку последовательности, поэтому все, что гарантирует C++, — это то, чтоx
будет увеличено дважды к тому моменту, когда программа перейдет к следующему оператору. C++ не указывает, увеличивается лиx
после вычисления каждого подвыражения или только после вычисления всех выражений, поэтому вам следует избегать операторов такого типа.
И я прочитал "Sequence Points and Expression Evaluation" Visual Systems Journal, август 2002 г. Клаус Крефт и Анжелика Лангер. Там было:
x[i]=i++ + 1;
Предположим, что переменная
i
имеет значение1
, прежде чем мы введем оператор. Что будет результатом вычисления этого выражения? Правильный ответ: мы не знаем. Однако программисты слишком часто полагают, что знают, что делает этот фрагмент программы. Типичные ответы включают: «x[1]
будет иметь значение2
», или «x[2]
будет иметь значение2
», или даже «x[1]
будет иметь значение3
».Третий вариант однозначно неверный. Этого не произойдет, потому что
i++
является приращением постфикса и возвращает начальное значениеi
1
; следовательно, значение правой части присваивания равно2
, а не3
. [...] Пока все хорошо, но мы не знаем, какая запись массиваx
будет изменена. Будет ли индекс1
или2
, когда значение правой части будет присвоеноx[i]
?На этот вопрос нет однозначного ответа. Это полностью зависит от порядка, в котором компилятор оценивает подвыражения. Если компилятор начнет с правой стороны присваивания и вычислит
i++ + 1
до того, как он определит, какой позиции в массиве нужно присвоитьx
, тогдаx[2]
будет изменено, посколькуi
уже было увеличено в ходе вычисления подвыраженияi++
. И наоборот, если компилятор начинает с левой стороны и выясняет, что он должен присвоить позициюi
в массивеx
, которая в это время все еще будет позицией1
, прежде чем он вычислит правую часть, тогда мы получим модификацияx[1]
. Оба исхода равновероятны и одинаково правильны. "
Как понять, где находится подвыражение? 4 + x++
и 6 + x++
являются подвыражениями, потому что они заключены в круглые скобки? x[i]
и i++ + 1
являются частью выражения? Почему? Меня это интересует, потому что я хочу понять, где в гипотезе может произойти побочный эффект.
a + b
сначала нужно оценитьa
иb
. Что не является последовательностями, так этоa
иb
по отношению друг к другу. Или, что в вашем коде проблематично, так это два отдельных выраженияx++
по отношению друг к другу. Поскольку ни один из них не упорядочен перед другим, программа имеет неопределенное поведение. - person Kerrek SB   schedule 26.04.20164 + x++
когда-либо был двусмысленным.x++
оценивается перед+
. Проблема исходит от другогоx++
. Причины могли измениться, но я считаю, что это всегда было неопределенным поведением. Никогда не гарантировалось, чтоx
будет увеличено дважды. - person Kerrek SB   schedule 26.04.2016