Короткий ответ: у вас там неопределенное поведение.
Точный ответ зависит от того, какой стандарт вы используете.
До C ++ 11, у нас было понятие порядковые точки .Интуитивно понятно, что это точки, в которых все значения были правильно сохранены, например, в конце оператора (в точке с запятой).Стандарт гласит, что
Между предыдущей и следующей точкой последовательности скалярный объект должен иметь свое сохраненное значение, измененное не более одного раза путем вычисления выражения.
, чтоозначает, что между 2 точками последовательности (для простоты читайте как между 2 точками с запятой) значение переменной не может быть изменено более одного раза.Вы изменяете значение дважды, используя оператор приращения.
C ++ 11 убрал понятие точек последовательности с отношениями , секвенированными до , , секвенированными после или unsequenced , ссылаясь на порядок, в котором вычисляются выражения.
В арифметических выражениях
Если побочный эффект на скалярном объекте не секвенирован относительно другогопобочный эффект для того же скалярного объекта или [...] поведение не определено.
и нет последовательности между операторами арифметического выражения.Поэтому это все еще случай неопределенного поведения, просто по другой причине.
На практике это означает, что компилятор может выбирать, что делать, и, в вашем случае, он выдает результаты, которые вы наблюдаете.Вы должны стараться как можно больше избегать неопределенного поведения в своих программах.Ниже приведены некоторые ссылки на эту тему:
https://en.cppreference.com/w/cpp/language/eval_order
Неопределенные точки поведения и последовательности