Говоря в контексте стандарта C++ 11 (который, как вы знаете, уже не имеет понятия точек последовательности), я хочу понять, как определяются два простых примера.Порядок оценки и неопределенного поведения
int i = 0;
i = i++; // #0
i = ++i; // #1
На SO есть две темы, которые объясняют эти примеры в контексте C++ 11. Here было сказано, что #0
вызывает UB и #1
четко определен. Here было сказано, что оба примера не определены. Эта двусмысленность меня смущает. Я читал это хорошо структурированное reference три раза, но тема кажется слишком сложной для меня.
.
Давайте проанализируем пример : i = i++;
.
Соответствующие цитаты:
Значение вычисления встроенного postincrement и postdecrement операторов секвенировали перед его побочным эффектом.
Побочный эффект (модификация левого аргумента) из встроенных в оператора присваивания и всех встроенных операторов присваивания секвенируют после вычисления значения (но не побочные эффекты) из и левой и правые аргументы, и секвенировали до вычисления выражения присваивания значения (то есть, перед возвращением ссылки на модифицированном объект)
Если побочный эффект от скалярного объекта unsequenced по отношению к другой стороне эффект на один и тот же скалярный объект, поведение не определено.
Как я понимаю, побочный эффект оператора присваивания не секвенировали с побочными эффектами от его левой и правой аргументы. Таким образом, побочный эффект оператора присваивания не секвенирован с побочными эффектами i++
. Итак, #0
вызывает UB.
.
Давайте проанализируем пример #1
: i = ++i;
.
Соответствующие цитаты:
Побочный эффект встроенных прединкремента и predecrement операторов секвенируют до его вычисления значений (неявное правило из-за к определению, как присвоение соединения)
Побочный эффект (модификация левого аргумента) встроенного оператора присваивания и всех встроенных операторов присваивания соединений секвенировали после вычисления значения (но не побочные эффекты) из и левых и правых аргументов, и секвенировали до вычисления значения выражения присваивания (то есть, прежде чем вернуться ссылка на модифицированном объекта)
Если побочный эффект скалярного объекта не зависит от другого побочного эффекта на том же скалярном объекте, поведение не определено.
Я не могу видеть, как этот пример отличается от #0
. Кажется, это UB для меня по той же причине, что и #0
. Побочный эффект назначения не секвенирован с побочным эффектом ++i
. Кажется, это UB. Приведенная выше тема говорит, что она четко определена. Зачем?
.
Вопрос: как я могу применить процитированные правила для определения UB из примеров. Было бы очень полезно получить как можно более простое объяснение. Спасибо!
У меня был бы довольно откровенный разговор с программистом, если бы я увидел это в производственном коде. Да, это интеллектуальное curiorisity, но не может видеть много заслуг в том, чтобы думать об этом слишком тяжело. Это, сказал, +1 для хорошо написанного вопроса, и я подробно прочитаю принятый ответ. – Bathsheba
@ Bathsheba Я согласен, что эти примеры кода, вероятно, никогда не будут в реальном коде, но я думаю, что понимание стандарта поможет определить UB в некоторых других примерах. – Kolyunya
Я поддержал вас по качеству вопроса и, как и вы, дождался ответа подобного качества. – Bathsheba