Técnicamente, en general, esto es un comportamiento indefinido .
Pero hay dos aspectos importantes de la respuesta.
La declaración de código:
std::cout << a++ << a;
se evalúa como:
std::operator<<(std::operator<<(std::cout, a++), a);
El estándar no define el orden de evaluación de los argumentos de una función.
Entonces O bien:
std::operator<<(std::cout, a++) se evalúa primero o
ase evalúa primero o
- podría ser cualquier orden definido por la implementación.
Este pedido no está especificado [Ref 1] según el estándar.
[Ref 1] C ++ 03 5.2.2 Llamada de función,
párrafo 8
El orden de evaluación de los argumentos no está especificado . Todos los efectos secundarios de las evaluaciones de expresiones de argumentos entran en vigor antes de que se introduzca la función. El orden de evaluación de la expresión de sufijo y la lista de expresiones de argumento no está especificado.
Además, no hay un punto de secuencia entre la evaluación de argumentos a una función, pero existe un punto de secuencia sólo después de la evaluación de todos los argumentos [Ref 2] .
[Ref 2] C ++ 03 1.9 Ejecución del programa [intro.execution]:
Para 17:
Cuando se llama a una función (esté o no en línea), hay un punto de secuencia después de la evaluación de todos los argumentos de la función (si los hay) que tiene lugar antes de la ejecución de cualquier expresión o declaración en el cuerpo de la función.
Tenga en cuenta que, aquí cse accede al valor de más de una vez sin un punto de secuencia intermedio, con respecto a esto, el estándar dice:
[Ref 3] C ++ 03 5 Expresiones [expr]:
Para 4:
....
Entre el punto de secuencia anterior y siguiente, un objeto escalar tendrá su valor almacenado modificado como máximo una vez mediante la evaluación de una expresión. Además, solo se accederá al valor anterior para determinar el valor que se almacenará . Los requisitos de este párrafo deberán cumplirse para cada ordenamiento permitido de las subexpresiones de una expresión completa; de lo contrario, el comportamiento no está definido .
El código se modifica cmás de una vez sin intervenir un punto de secuencia y no se accede a él para determinar el valor del objeto almacenado. Esta es una clara violación de la cláusula anterior y, por lo tanto, el resultado según lo ordena el estándar es un comportamiento indefinido [Ref 3] .