Как работает x = x++ и x = ++x?

Пусть x = 5. Тогда в обоих случаях cout << x даст 6. Но в случае x = x++, кажется, что работать должно так:

  1. Отрабатывает x++: заведется переменная y, куда положится 5. Затем x увеличится на 1. Итого возвращается значение 5, а x = 6.
  2. Отрабатывает присваивание: переменной x=6 присваивается значение 5. Подскажите, пожалуйста, где ошибка в понимании работы?

Ответы (3 шт):

Автор решения: Doonort3

++X; //Префикс

X++; //Постфикс

Префикс увеличивает значение, а затем высчитывает выражение. Постфикс высчитывает выражение, а затем осуществляет увеличение.

x = 5;
y = ++x //Получится 6
z = x++ //присваевает значение x к z, а затем производит его вычесление. получится 6, так как z присвоил значение x, а потом увеличил его на единицу.
→ Ссылка
Автор решения: HolyBlackCat

До C++17 оба варианта вызывают неопределенное поведение, см. order of evaluation.

Начиная с C++17, насколько я понял, x = x++ не меняет значение x, а x = ++x увеличивает его на 1.

Объяснение в вопросе правильное. Если ваш компилятор дает другой результат, то или он не поддерживает C++17, или в нем баг.

Последние GCC и Clang выдают правильный результат, хотя почему-то с предупреждениями.

→ Ссылка
Автор решения: 232_159

Рассмотрим первый пример x = ++x;

Сначала будет посчитано значение справа от знака присваивания, а затем будет выполнено само присваивание.

1) Выполнение преинкремента. Значение x увеличивается на единицу и возвращается новое значение x-а.

2) Выполняется оператор присваивания.

т.е можно расписать вот так:

x = x + 1;  (преинкремент)

x = x;  (присваивание)

Если изначально x равнялся 5, то его значение, после этих операций, будет 6

Второй пример x = x++;

1) Выполнение постинкремента. Говорят, что сначала возвращается значение x, а потом увеличение x-а на 1. На самом деле снимается копия с переменной x, происходит инкремент, возвращение старого значения x (копии)

2) Выполняется оператор присваивания.

т.е можно расписать вот так:

auto y = x;

x = x + 1;  (постинкремент)

x = y;  (операция вернула y (копию старого значения x))

Т.е если в начале x = 5, то операция постинкремента вернет 5 (хотя значение x-а в этот момент равно 6-ти), а затем вызовется оператор присваивания и x (в котором все еще лежит 6) затерется результатом операции постинкремента (ну т.е. 5)

В результате во втором примере в x лежит 5

→ Ссылка