En c / c ++, ¿se apilan las variables de ámbito de bloque solo si se ejecuta el bloque?

8

Supongamos esto:

void func()
{
 ...
 if( blah )
 {
  int x;
 }
 ...
}  

¿Se xreserva el espacio para la pila inmediatamente cuando funcse ingresa, o solo si el bloque se ejecuta realmente?
¿O es la elección del compilador?
¿C y C ++ se comportan igual sobre esto?

Petruza
fuente
1
Esa es la implementación definida, por lo que debe ver algunos ejemplos de código generado por diferentes compiladores para tener una idea. En esta charla de Microsoft , el presentador habla brevemente sobre lo que llama "empaquetado de la pila" en el compilador de VisualC ++, que probablemente sea una optimización para asignar solo el espacio de pila mínimo necesario para cada función.
glampert

Respuestas:

12

Quién dijo que el compilador reservará cualquier espacio (solo puede registrarse).

Esto es completamente indefinido.
Todo lo que puede decir es que xsolo se puede acceder a él ( ) desde el interior del bloque interno.

La forma en que el compilador asigna memoria (en una pila, si es que existe) depende completamente del compilador (ya que la región de memoria puede reutilizarse para múltiples objetos (si el compilador puede probar que sus vidas no se superponen)).

Es el espacio para x reservado en la pila inmediatamente cuando se ingresa func

Indeterminado.

o solo si el bloque se ejecuta realmente?

Indeterminado.
Pero si xse tratara de un objeto de clase, el constructor solo se ejecutará si se ingresa el bloque.

¿O es la elección del compilador?

Es posible que el compilador ni siquiera asigne memoria.

¿C y C ++ se comportan igual sobre esto?

si

Martin York
fuente
3
Yo diría que preocuparse demasiado por cómo maneja el compilador esto sería una optimización prematura para la mayoría de las aplicaciones.
TehShrike
4

Bueno, es realmente la elección del compilador, pero lo que he observado es que cuando compilo sin optimizaciones , (que es lo que solemos hacer para poder depurar nuestro código), el compilador tiende a hacer las cosas de una manera bastante clara. corte, moda determinista y confiable:

  • El compilador no optimizar distancia cualquier variables locales. (Excepto, tal vez, variables definidas explícitamente como register, pero eso debe ser verificado).

  • El espacio de pila para todas las variables locales, sin importar cómo estén anidadas, se reserva de inmediato cuando se ingresa la función.

  • El espacio de pila no se reutiliza en ámbitos anidados separados. Esto significa que void f(){ { int x; } { int y; } }asignará espacio para dos intvariables; el espacio asignado para xlo que no puede volver a utilizar para y.

Por supuesto, si habilita las optimizaciones, todo lo que Loki Astari escribió en la respuesta aceptada es cierto.

Mike Nakis
fuente