Comportamiento del incremento posterior en cout

#include  using namespace std; main(){ int i = 5; cout << i++ << i--<< ++i << --i << i << endl; } 

El progtwig anterior comstackdo con g ++ da salida:

 45555 

Mientras que el siguiente progtwig:

 int x=20,y=35; x =y++ + y + x++ + y++; cout << x<< endl << y; 

da resultado como

 126 37 

¿Alguien puede explicar la salida?

 cout << i++ << i-- 

es semánticamente equivalente a

 operator<<(operator<<(cout, i++), i--); <------arg1--------->, <-arg2-> 

$ 1.9 / 15- "Cuando se llama a una función (esté o no en línea), cada cómputo de valor y efecto secundario asociado con cualquier expresión de argumento, o con la expresión de postfijo que designa la función llamada, se secuencia antes de la ejecución de cada expresión o statement en el cuerpo de la función llamada. [ Nota: los cómputos de valor y los efectos secundarios asociados con las diferentes expresiones de argumento no se han secuenciado. -finalizar nota ]

C ++ 0x:

Esto significa que la evaluación de los argumentos arg1 / arg2 no se está secuenciando (ninguno de ellos está secuenciado antes que el otro).

La misma sección en el proyecto de Norma también establece:

Si un efecto secundario en un objeto escalar no se está secuenciando en relación con otro efecto secundario en el mismo objeto escalar o con un cálculo de valor que utiliza el valor del mismo objeto escalar, el comportamiento no está definido.

Ahora hay un punto de secuencia en el punto y coma al final de la expresión completa a continuación

 operator<<(operator<<(cout, i++), i--); ^ the interesting sequence point is right here 

Como es evidente, la evaluación de ambos arg1 y arg2 conduce a un efecto secundario sobre la variable escalar 'i', y como vimos anteriormente, los efectos secundarios no son secuenciados.

Por lo tanto, el código tiene un comportamiento indefinido. ¿Entonces que significa eso?

Así es como se define 'comportamiento indefinido' 🙂 en el Estándar.

El comportamiento indefinido permitido va desde ignorar la situación completamente con resultados impredecibles, hasta comportarse durante la traducción o la ejecución del progtwig de una manera documentada característica del entorno (con o sin la emisión de un mensaje de diagnóstico) hasta terminar una traducción o ejecución (con la emisión de un mensaje de diagnóstico). Muchos constructos erróneos del progtwig no engendran un comportamiento indefinido; se requiere que sean diagnosticados.

¿Ve la correlación con la respuesta de @ DarkDust? Incluso se le permite al comstackdor encender su computadora 🙂 '

Por lo tanto, cualquier resultado que obtenga de dicho código se encuentra realmente en el temido ámbito del comportamiento indefinido.

No lo hagas

Lo único que se defined sobre dicho código es que ayuda a OP y muchos de nosotros recibimos muchos votos (si se responde correctamente) 🙂

El resultado de la expresión del segundo progtwig no está definido. El comstackdor incluso puede encender su computadora 🙂 No tiene permitido modificar una variable dos veces dentro de un punto de secuencia (en este caso: de = a ; ).

Editar:

Para explicaciones detalladas, consulte las preguntas frecuentes de C , específicamente la pregunta 3.2 .

Agregando a las respuestas de otros:

Si está usando g++ , usar la opción -Wsequence-point dice que:

 $ g++ -Wsequence-point a.cpp a.cpp: In function 'int main()': a.cpp:8: warning: operation on 'i' may be undefined ^^^^^^^^^ 

Comportamiento indefinido, por lo que cualquier cosa podría pasar