c++ undefined-behavior

c++ - i=i++; es indefinido. ¿Es i=foo(i++) también indefinido?



undefined-behavior (2)

La última oración de su cita dice "que no está secuenciada específicamente antes o después de la ejecución del cuerpo de la función llamada" por lo que la pregunta es si el incremento y la asignación "están secuenciadas específicamente antes o después" del cuerpo de la función.

1.9 [intro.execution] p15 tiene la respuesta:

Cuando se llama a una función (ya sea que la función esté o no en línea), cada cálculo de valor y efecto secundario asociado con cualquier expresión de argumento, o con la expresión de posfijo que designa la función llamada, se secuencia antes de la ejecución de cada expresión o declaración en el cuerpo del llamada función. [ Nota: los cálculos de valor y los efectos secundarios asociados con diferentes expresiones de argumentos no tienen secuencia. - nota final ]

Entonces, el incremento de i ocurre antes del cuerpo de la función, y la asignación a i ocurre después de que la función regresa, por lo que está perfectamente bien definida.

En la terminología anterior a C ++ 11, la llamada a la función introduce un punto de secuencia entre el incremento y la asignación.

Por ejemplo:

int foo(int i) { return i; } int main() { int i = 0; i = i++; // Undefined i = foo(i++); // ? return 0; }

¿Qué especificaría la norma ISO C ++ actual para este caso?

EDITAR:

Aquí es donde me confundo:

Excepto donde se indique, las evaluaciones de los operandos de operadores individuales y de las subexpresiones de expresiones individuales no tienen secuencia.

Si un efecto secundario en un objeto escalar no tiene secuencia en relación con otro efecto secundario en el mismo objeto escalar o un cálculo de valor utilizando el valor del mismo objeto escalar, y no son potencialmente concurrentes (1.10), el comportamiento no está definido.

En todos los casos, la asignación se secuencia después del cálculo del valor de los operandos derecho e izquierdo, y antes del cálculo del valor de la expresión de asignación

Cada evaluación en la función de llamada (incluidas otras llamadas de función) que no está secuenciada específicamente antes o después de la ejecución del cuerpo de la función llamada se secuencia de forma indeterminada con respecto a la ejecución de la función llamada.

Así que parece que podría tener un cálculo de valor en el lado izquierdo de la asignación (solo i ), y un efecto secundario en el lado derecho (la modificación de i de i++ ) que no están secuenciados uno con respecto al otro.

EDIT2 :

Para cualquier persona que se encuentre aquí, hay una gran explicación sobre la secuenciación que encontré here .


i = foo(i++); está bien, porque i++ se ejecuta antes de llamar a foo() . Se crea una copia de i , luego se incrementa, luego la copia se pasa a foo() . Es lo mismo que hacer esto explícitamente:

int tmp = i++; i = foo(tmp);