c++ c++11 undefined-behavior c++17

c++ - Comportamiento indefinido en el uso repetido del operador prefix++



c++11 undefined-behavior (2)

Leí esta answer sobre un comportamiento indefinido, donde vi la siguiente declaración:

++++++i; // UB, parsed as (++(++(++i)))

No creo que sea un comportamiento indefinido. Tengo una duda, ¿es realmente UB en C ++? ¿Si es así, entonces cómo?

Además, hice el programa y lo compilé usando el g++ prog.cpp -Wall -Wextra -std=gnu++1z -pedantic , funciona bien sin ninguna advertencia. Es dar una salida esperada.

#include <iostream> using namespace std; int main() { int i = 0; cout<<++++++i<<endl; }


A veces, el comportamiento no está definido, aunque es difícil imaginar cómo podría ser mal manejado. Pero antes de C ++ 11, esto no estaba definido porque el mismo objeto se modifica varias veces sin una secuencia intermedia señalada.

Uno podría imaginar un compilador que "optimizó" el código al consolidar todas las modificaciones en i . Así, cada incremento termina incrementando el valor original. Pero ese no es el punto. UB es UB si el estándar lo dice. No importa si podemos o no imaginar formas en que puede fallar.


En C ++ 03 es un comportamiento indefinido. En C ++ 11 no lo es. No hay un punto de secuencia entre los distintos preincrementos. Si i fuera un tipo definido por el usuario, sería un comportamiento bien definido porque entonces habría una llamada de función (un punto de secuencia).

En C ++ 11, la idea de puntos de secuencia se reemplazó con secuencia antes / secuenciada después. El defecto 637 ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637 ) proporciona un ejemplo de un constructo previamente no definido que se está definiendo ( i = ++i + 1 ) .

Para comprender por qué no es un comportamiento indefinido, veamos las piezas que necesitamos. ++i es equivalente a i = i + 1 (excepto que solo se evalúa una vez). Además, si sustituimos i = i + 1 con inc , ++(i = i + 1) convierte en inc = inc + 1 .

[expr.ass] estados:

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.

Por lo tanto, la asignación en i = i + 1 se secuencia antes del cálculo del valor de inc ; sin embargo, la asignación en inc = inc + 1 se secuencia después del cálculo del valor de inc . No hay un comportamiento indefinido porque las asignaciones están secuenciadas.