Возможный дубликат:
вычисления непоследовательных значений (иначе точки следования )
Неопределенное поведение и точки последовательности
Приоритет оператора и порядок оценки
Я все еще пытаюсь понять, как следующее выражение приводит к неопределенному поведению:
a = a++;
При поиске SO по этому поводу я нашел следующий вопрос:
Разница между точками следования и приоритетом оператора? 0_о
Я прочитал все ответы, но у меня все еще есть трудности с деталями. Один из ответов описывает поведение моего приведенного выше примера кода как неоднозначное с точки зрения того, как изменяется a
. Например, это может сводиться к любому из этих:
a=(a+1);a++;
a++;a=a;
Что именно делает модификацию a
неоднозначной? Связано ли это с инструкциями ЦП на разных платформах и как оптимизатор может воспользоваться неопределенным поведением? Другими словами, он кажется неопределенным из-за сгенерированного ассемблера?
Я не вижу причин для компилятора использовать a=(a+1);a++;
, это просто выглядит причудливо и не имеет особого смысла. Что могло бы заставить компилятор вести себя таким образом?
РЕДАКТИРОВАТЬ:
Просто чтобы быть ясным, я понимаю, что происходит, я просто не понимаю, как это может быть неопределенным, когда есть правила приоритета операторов (которые, по сути, определяют порядок вычисления выражения). В этом случае присваивание происходит последним, поэтому a++
необходимо оценить первым, чтобы определить значение, которое нужно присвоить a
. Итак, я ожидаю, что a
сначала модифицируется во время приращения post-fix, но затем дает значение, которое можно присвоить обратно a
(вторая модификация). Но правила приоритета операторов, кажется, делают поведение очень понятным для меня, я не могу найти, где есть какое-либо «пространство для маневра», чтобы оно имело неопределенное поведение.
a
дважды без точки следования: один раз в назначении и один раз как побочный эффект++
. Стандарт не указывает, что вы имеете в виду. - person Kerrek SB   schedule 07.09.2012a
дважды модифицируется, я спрашиваю, что именно в нем не определено. В стандарте не указано, что вы имеете в виду -- Что? Он указывает порядок операций и приоритет операторов, он очень ясно дает понять, что означает выражение. Я могу смотреть на это и знать, что происходит, по порядку. - person void.pointer   schedule 07.09.2012*p++
, что означает(*p)++
), он не помогает определить порядок, в котором происходят модификации объекта. - person jrok   schedule 07.09.2012a
в одном и том же выражении. Почему вы хотите это сделать? В этом нет абсолютно никакой практической пользы. - person Bo Persson   schedule 07.09.2012a
дважды, так какая нам разница?++a
будет работать нормально,a = a++ + ++a - a--
- нет. Используйте тот, который работает! - person Bo Persson   schedule 07.09.2012