2010-11-22 18 views

Respuesta

9

observe ese valor será lo que usted reclama, así es como UB puede manifestarse entre otros escenarios posibles. El programa puede generar lo que espera, generar datos no relacionados, bloquear datos corruptos o gastar toda su pizza de pedidos de dinero. Una vez que el estándar de C++ dice que algún constructo es UB, no debes esperar ningún comportamiento específico. Los resultados observados pueden variar de un programa ejecutado a otro.

+0

pero ¿cómo podría el resultado ser diferente de 2? Probé algunos compiladores en línea y fuera de línea, incluidos gcc, msvC++, intel C++. no recibí nada diferente de 2. – AMS

+1

@AMS: ¿Qué pasa si el programa también gastó todo su dinero o envió todas sus contraseñas a un tercero (http://stackoverflow.com/questions/908872/whats-the-worst-example- of-undefined-behavior-actually-possible/3554343 # 3554343)? – sharptooth

+0

Y eso no es una broma en absoluto: lo aliento a que realmente siga el enlace y lea la respuesta detrás de él. – sharptooth

0

De exactamente el mismo enlace que está proporcionando:

  • Además, el valor previa se acceder sólo para determinar el valor a almacenar.

¿Qué significa? Significa que si un objeto se escribe dentro de una expresión completa , todos los accesos a él dentro de la misma expresión deben ser directamente implicados en el cálculo del valor que se escribirá.

Aquí en el lado izquierdo del operador =, el acceso a i no está involucrado en el cálculo del valor escrito.

0

++ i (debería ser) un valor r, y por lo tanto, no se puede usar como lvalue, pero (++ i) = 2; debería funcionar bien No creo que esto sea UB, pero, como siempre, podría estar equivocado.

+0

Sí, estás equivocado. Agregar paréntesis no cambia el análisis sintáctico de esa expresión, el operador de prefijo ++ devuelve un valor l. El UB es el resultado de escribir dos veces el mismo lvalue en el mismo punto de secuencia. –

+0

@Greg Rogers: ¡Gracias! –

11

Parece obvio para usted, porque, obviamente, i se primera asignarse i+1, entonces segundo asignarse el valor 2.

Sin embargo, estas dos asignaciones suceda dentro de un mismo punto de la secuencia, por lo tanto, depende de que el compilador que pasa Frist y lo que ocurre en segundo lugar, por lo tanto, diferentes implementaciones del compilador puede generar código que le dará resultados diferentes, por lo tanto es UB .

+4

Yeap, y también el compilador no está obligado a producir el mismo programa en compilaciones diferentes. Imprime 0 en una compilación ane, borra el disco en otro. – sharptooth

1

Llamar a ++i = 2; no provoca en sí mismo un comportamiento indefinido; cualquier compilador puede, si lo desea, hacer una acción muy definida al llegar a ese código. Sin embargo, el estándar C++ establece que dicha operación no está definida, por lo tanto, un compilador puede hacer algo inesperado (como eliminar todos los archivos en la unidad C o enviar un mensaje de texto al papa) y seguir compilando. Lo único que hace este UB es que el estándar dice que es UB.

Quizás el punto más importante es que una versión de un compilador puede hacer algo diferente de la próxima versión del mismo compilador.

2

El comportamiento indefinido se debe a que un compilador podría implementar el siguiente código:

++i = 2; 

ya sea como:

i = 2; 
++i; 

o

++i; 
i = 2; 

Es no especificado en el lenguaje, un compilador podría elegir implementar cualquiera de los anteriores. El primero produciría 3 y el segundo 2. Entonces no está definido.

Cuestiones relacionadas