Cuando tengo un bucle y dentro de este bucle, creo una nueva variable de pila (sin asignarla en el montón y la variable que la mantiene declarada dentro del cuerpo del bucle), ¿se garantiza que se llamará al destructor de este objeto antes de que comience la próxima iteración, o podría ¿Desenrollar el bucle por el compilador cambia algo al respecto?
c++
destructor
usuario1282931
fuente
fuente
Respuestas:
De
n4800
:§6.3.3 Alcance del bloque :
§10.3.6 Destructores :
§4.1.1 Máquina abstracta :
[El énfasis es mío]
Entonces sí. Su variable queda fuera de alcance al final del ciclo (que es un bloque) y, por lo tanto, se llama a su destructor por lo que cualquiera que observe el comportamiento del programa puede ver .
fuente
call
editados. O, si efectivamente (como regla if) no hacen nada, puede que no se genere un ensamblaje para dichos destructores.Si. Es más fácil visualizar cuando considera los "bloques" en los que declara una variable, es decir, entre qué par de llaves. El ciclo es un bloque en sí mismo, y cuando alcanza el paréntesis de cierre, antes de la siguiente iteración, se llama a todos los destructores de variables de almacenamiento automático declaradas en el ciclo.
Como regla general, no piense en lo que optimizará el compilador, porque aún necesita garantizar el comportamiento de su programa, sin importar lo que haga para optimizarlo. En ese caso, el desenrollado de bucle no cambiará nada a ese efecto si sucede.
fuente
[class.copy.elision]
for(...) X x{};
y elx
objeto se construirá + destruirá en cada iteración. Demostración en vivo . Una sección estándar relevante es stmt.iter / 2 .[stmt.iter]
es puramente equivalente (énfasis mío): "Si la declaración en una declaración de iteración es una declaración única y no una declaración compuesta, es como si se hubiera reescrito para ser una declaración compuesta que contiene la declaración original ". En esencia, con o sin llaves para una sola declaración significa exactamente lo mismo y las llaves están implícitas. Lo omití por claridad.Se llama al destructor para cada iteración. Por lo tanto, en algunos casos es más rápido declarar una variable fuera del ciclo en lugar de hacerlo en el ciclo. Suponiendo el siguiente caso:
No se llama al destructor cuando se ejecuta el uso del bucle. Simplemente anula
temp
.Pero si usa
std::string temp = arr[i]
el constructor y se llama al destructor para cada iteración. Creo que esto agrega un poco de tiempo de ejecución en caso de que tenga un bucle que se ejecuta con mucha frecuencia.fuente
Se llama al destructor antes de la siguiente iteración
fuente
Por supuesto, se llama a dtor al final de la iteración y el desenrollado del bucle no debería modificar este comportamiento, como cualquier otra optimización (una optimización no debería modificar el comportamiento del programa), excepto algún tipo de RVO y similares que pueden eliminar algunas creaciones de objetos semánticamente espurios .
fuente