¿Es i = i ++ realmente un comportamiento indefinido?

Posible duplicado:
¿Alguien podría explicar estos comportamientos indefinidos (i = i ++ + ++ i, i = i ++, etc. …)

De acuerdo con el estándar C ++,

i = 3; i = i++; 

dará como resultado un comportamiento indefinido.

Usamos el término “comportamiento indefinido” si puede llevar a más de un resultado. Pero aquí, el valor final de i será 4 sin importar el orden de evaluación, entonces ¿no debería llamarse realmente “comportamiento no especificado”?

La frase “… el valor final de i será 4 sin importar el orden de evaluación …” es incorrecta. El comstackdor podría emitir el equivalente de esto:

 i = 3; int tmp = i; ++i; i = tmp; 

o esto:

 i = 3; ++i; i = i - 1; 

o esto:

 i = 3; i = i; ++i; 

En cuanto a las definiciones de los términos, si se garantiza que la respuesta es 4, eso no sería un comportamiento no especificado o indefinido, sino un comportamiento definido.

Tal como está, es un comportamiento indefinido de acuerdo con el estándar ( Wikipedia ), por lo que incluso es libre de hacer esto:

 i = 3; system("sudo rm -rf /"); // DO NOT TRY THIS AT HOME … OR AT WORK … OR ANYWHERE. 

No, no usamos el término “comportamiento indefinido” cuando simplemente puede generar más de un resultado aritmético . Cuando el comportamiento se limita a diferentes resultados aritméticos (o, de manera más general, a un conjunto de resultados predecibles ), se suele denominar comportamiento no especificado .

Comportamiento no definido significa consecuencias completamente impredecibles e ilimitadas, como formatear el disco duro en su computadora o simplemente hacer que su progtwig falle. Y i = i++ es un comportamiento indefinido .

De dónde sacó la idea de que debería tener 4 en este caso no está claro. No hay absolutamente nada en el lenguaje C ++ que te permita llegar a esa conclusión.

En C y también en C ++, el orden de cualquier operación entre dos puntos de secuencia depende completamente del comstackdor y no puede depender de él. El estándar define una lista de cosas que compone puntos de secuencia, de memoria esto es

  1. el punto y coma después de una statement
  2. el operador de coma
  3. evaluación de todos los argumentos de funciones antes de la llamada a la función
  4. el && y || operando

Al buscar la página en wikipedia, la lista es más completa y describe más en detalle. Los puntos de secuencia son un concepto extremadamente importante y si aún no sabe lo que significa, se beneficiará enormemente al aprenderlo de inmediato.

i = y i ++ son ambos efectos secundarios que modifican i.

i ++ no implica que solo se incrementa después de que se evalúa toda la statement, simplemente que se ha leído el valor actual de i. Como tal, la asignación y el incremento podrían ocurrir en cualquier orden.

1. No, el resultado será diferente dependiendo del orden de evaluación. No existe un límite de evaluación entre el incremento y la asignación, por lo que el incremento se puede realizar antes o después de la asignación. Considera este comportamiento:

 load i into CX copy CX to DX increase DX store DX in i store CX in i 

El resultado es que i contengo 3 , no 4 .

Como comparación, en C # hay un límite de evaluación entre la evaluación de la expresión y la asignación, por lo que el resultado siempre será 3 .

2. Incluso si no se especifica el comportamiento exacto, la especificación es muy clara sobre lo que cubre y lo que no cubre. El comportamiento se especifica como indefinido, no está especificado.

Para responder tu pregunta:

  1. Creo que un “comportamiento indefinido” significa que el comstackdor / implementador de lenguaje es libre de hacer lo que le parezca mejor, y no que pueda dar lugar a más de un resultado.
  2. Porque no está sin especificar . Está claramente especificado que su comportamiento no está definido .

No vale la pena escribir i = i ++ cuando simplemente puede escribir i ++.