Технически в целом это неопределенное поведение .
Но есть два важных аспекта ответа.
Заявление кода:
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 Выполнение программы [intro.execution]:
Пункт 17:
При вызове функции (независимо от того, является ли функция встроенной), после оценки всех аргументов функции (если есть), которая имеет место перед выполнением любых выражений или операторов в теле функции, существует точка последовательности.
Обратите внимание, что здесь к значению c
обращаются более одного раза без промежуточной точки последовательности, относительно этого в стандарте говорится:
[Ссылка 3] C ++ 03 5 Выражения [expr]:
Пункт 4:
....
Между предыдущей и следующей точкой последовательности скалярный объект должен иметь свое сохраненное значение, измененное не более одного раза при оценке выражения. Кроме того, к предыдущему значению необходимо обращаться только для определения значения, которое необходимо сохранить . Требования данного параграфа должны соблюдаться для каждого допустимого порядка подвыражений полного выражения; в противном случае поведение не определено .
Код изменяется c
более одного раза без вмешательства точки последовательности, и к нему не осуществляется доступ для определения значения сохраненного объекта. Это явное нарушение вышеупомянутого пункта и, следовательно, результатом, предписываемым стандартом, является Undefined Behavior [Ref 3] .