Em c / c ++, as variáveis ​​de escopo do bloco são empilhadas apenas se o bloco for executado?

8

Suponha isso:

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

O espaço xreservado para a pilha é imediatamente funcinserido, ou apenas se o bloco for realmente executado?
Ou é a escolha do compilador?
C e C ++ se comportam da mesma maneira sobre isso?

Petruza
fonte
1
Como a implementação é definida, você deve examinar alguns exemplos de código gerado por diferentes compiladores para ter uma idéia. Nesta palestra da Microsoft , o apresentador fala brevemente sobre o que ele chama de "empilhamento de pilhas" no compilador VisualC ++, que provavelmente é uma otimização para alocar apenas o espaço mínimo necessário para cada função.
glampert

Respostas:

12

Quem disse que o compilador reservará qualquer espaço (poderia ser apenas um registro).

Isso é completamente indefinido.
Tudo o que você pode dizer é que ( x) só pode ser acessado de dentro do bloco interno.

A maneira como o compilador aloca memória (em uma pilha, se existir) é totalmente dependente do compilador (como a região da memória pode ser reutilizada para vários objetos (se o compilador puder provar que sua vida útil não se sobrepõe)).

É o espaço para x reservado na pilha imediatamente quando func é inserido

Indeterminado.

ou apenas se o bloco for realmente executado?

Indeterminado.
Mas se xera um objeto de classe, o construtor só será executado se o bloco for inserido.

Ou é a escolha do compilador?

O compilador pode nem mesmo alocar memória.

C e C ++ se comportam da mesma maneira sobre isso?

sim

Martin York
fonte
3
Eu diria que se preocupar demais com o modo como o compilador lida com isso seria uma otimização prematura para a maioria dos aplicativos.
TehShrike
4

Bem, é realmente a escolha do compilador, mas o que observei é que, quando compilo sem otimizações (o que geralmente fazemos para poder depurar nosso código), o compilador tende a fazer as coisas de maneira bastante clara. moda cortada, determinística e confiável:

  • O compilador não otimiza nenhuma variável local. (Exceto, talvez, variáveis ​​explicitamente definidas como register, mas isso deve ser verificado.)

  • O espaço de pilha para todas as variáveis ​​locais, independentemente de como estão aninhadas, é reservado imediatamente quando a função é inserida.

  • O espaço da pilha não é reutilizado em escopos aninhados separados. Isso significa que void f(){ { int x; } { int y; } }alocará espaço para duas intvariáveis; o espaço alocado para xo não ser reutilizado para y.

Obviamente, se você ativar otimizações, tudo o que Loki Astari escreveu na resposta aceita é verdadeiro.

Mike Nakis
fonte