c++ language-lawyer undefined-behavior c++03 sequence-points

¿* &++ causa un comportamiento indefinido en C++ 03?



language-lawyer undefined-behavior (2)

En otra respuesta , se indicó que antes de C ++ 11, donde i es un int , entonces use la expresión:

*&++i

Causó un comportamiento indefinido. ¿Es esto cierto?

En la otra respuesta hubo una pequeña discusión en los comentarios, pero parece poco convincente.


Creo que la pregunta solo tiene sentido si tratamos con la expresión:

i = *&++i;

La cita relevante en el estándar C ++ 03 sería [expr] / 4:

Excepto donde se indique, el orden de evaluación de los operandos de los operadores individuales y las subexpresiones de las expresiones individuales, y el orden en el que tienen lugar los efectos secundarios, no se especifica. Entre el punto de secuencia anterior y el siguiente, un objeto escalar tendrá su valor almacenado modificado a lo sumo una vez por la evaluación de una expresión. Además, se debe acceder al valor anterior solo para determinar el valor que se almacenará. Los requisitos de este párrafo se cumplirán para cada ordenamiento permitido de las subexpresiones de una expresión completa; De lo contrario el comportamiento es indefinido.

i = ++i + 1; // the behavior is unspecified

Simplemente podemos comparar la secuencia de i = *&++i vs i = ++i + 1 para determinar que la misma regla hace que ambas no estén especificadas. Ambos son declaraciones de la forma:

i = f(++i);

Para cualquier función f , la lectura de i en el lado izquierdo y el efecto secundario de ++i en el lado derecho no se secuencian entre sí. Por lo tanto, el comportamiento indefinido.


No tiene mucho sentido preguntar si *&++i en sí mismo tiene UB. La referencia no necesariamente tiene acceso al valor almacenado (anterior o nuevo) de i , como puede ver al usar esto como una expresión de inicialización para una referencia. Solo si se trata de una conversión de valor (uso en ese contexto) hay alguna pregunta para discutir. Y luego, ya que podemos usar el valor de ++i , podemos usar el valor de *&++i con exactamente las mismas advertencias que para ++i .

La pregunta original se refería esencialmente a i = ++i , que es lo mismo que i = *&++i . Ese fue un comportamiento indefinido en C ++ 03, debido a que se modificó dos veces entre los puntos de secuencia, y está bien definido en C ++ 11, debido a que los efectos secundarios del operador de asignación se secuenciaron después de los cálculos de valores de la izquierda y laterales derechos.

Quizás sea relevante tener en cuenta que los ejemplos no normativos en los estándares C ++ 98 y C ++ 03 fueron incorrectos, y describieron algunos casos de comportamiento indefinido formalmente como un comportamiento simplemente no especificado. Por lo tanto, la intención no ha sido del todo clara, todo el camino de regreso. Una buena regla general es no basarse simplemente en los casos oscuros de las esquinas del idioma para evitarlos: no es necesario ser un abogado de idiomas para entender el código ...