Технічно загалом це невизначена поведінка .
Але у відповіді є два важливі аспекти.
Заява коду:
std::cout << a++ << a;
оцінюється як:
std::operator<<(std::operator<<(std::cout, a++), a);
Стандарт не визначає порядок оцінки аргументів функції.
Так чи то:
std::operator<<(std::cout, a++)
оцінюється спочатку або
a
оцінюється спочатку або
- це може бути будь-який порядок, визначений реалізацією.
Це замовлення не визначено [Посилання 1] відповідно до стандарту.
[Посилання 1] C ++ 03 5.2.2 Виклик функції
Пара 8
Порядок оцінки аргументів не визначений . Всі побічні ефекти оцінок виразів аргументів набувають чинності перед введенням функції. Порядок оцінки виразу постфікса та список виразів аргументів не визначений.
Крім того, між оцінкою аргументів функції немає точки послідовності, але точка послідовності існує лише після оцінки всіх аргументів [Посилання 2] .
[Посилання 2] C ++ 03 1.9 Виконання програми [введення.виконання]:
Параграф 17:
Під час виклику функції (незалежно від того, чи функція є вбудованою чи ні), після оцінки всіх аргументів функції (якщо такі є) має місце послідовність, яке має місце перед виконанням будь-яких виразів або висловлювань в тілі функції.
Зауважте, що тут значення c
доступу отримується не раз без втручальної точки послідовності, щодо цього стандарт говорить:
[Посилання 3] C ++ 03 5 Вирази [expr]:
Параграф 4:
....
Між попередньою та наступною точкою послідовності скалярний об'єкт повинен змінити його збережене значення якнайбільше одночасно оцінкою виразу. Крім того, попереднє значення має доступ лише для визначення значення, яке потрібно зберігати . Вимоги цього пункту повинні бути дотримані для кожного допустимого впорядкування підвиразів повного виразу; інакше поведінка не визначена .
Код змінюється c
неодноразово, не втручаючись точку послідовності, і до нього не можна отримати доступ для визначення значення збереженого об'єкта. Це явне порушення вищезазначеного пункту, а отже, результатом, визначеним стандартом, є Невизначена поведінка [Посилання 3] .