Memória alocada em tempo de compilação significa que o compilador resolve em tempo de compilação, onde certas coisas serão alocadas dentro do mapa de memória do processo.
Por exemplo, considere uma matriz global:
int array[100];
O compilador sabe em tempo de compilação o tamanho da matriz e o tamanho de um int
, portanto, conhece todo o tamanho da matriz em tempo de compilação. Além disso, uma variável global tem duração de armazenamento estático por padrão: é alocada na área de memória estática do espaço de memória do processo (seção .data / .bss). Dadas essas informações, o compilador decide durante a compilação em qual endereço da área de memória estática a matriz será .
É claro que os endereços de memória são endereços virtuais. O programa assume que ele possui todo o seu próprio espaço de memória (de 0x00000000 a 0xFFFFFFFF, por exemplo). É por isso que o compilador pode fazer suposições como "Ok, a matriz estará no endereço 0x00A33211". No tempo de execução, esses endereços são traduzidos para endereços reais / de hardware pelo MMU e pelo SO.
Valor inicializado armazenamento estático coisas são um pouco diferentes. Por exemplo:
int array[] = { 1 , 2 , 3 , 4 };
Em nosso primeiro exemplo, o compilador decidiu apenas onde a matriz será alocada, armazenando essas informações no executável.
No caso de itens inicializados por valor, o compilador também injeta o valor inicial da matriz no executável e adiciona código que informa ao carregador do programa que após a alocação da matriz no início do programa, a matriz deve ser preenchida com esses valores.
Aqui estão dois exemplos do assembly gerado pelo compilador (GCC4.8.1 com destino x86):
Código C ++:
int a[4];
int b[] = { 1 , 2 , 3 , 4 };
int main()
{}
Conjunto de saída:
a:
.zero 16
b:
.long 1
.long 2
.long 3
.long 4
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
popq %rbp
ret
Como você pode ver, os valores são injetados diretamente na montagem. Na matriz a
, o compilador gera uma inicialização zero de 16 bytes, porque o Padrão diz que itens armazenados estáticos devem ser inicializados como zero por padrão:
8.5.9 (Inicializadores) [Nota]:
Todo objeto com duração de armazenamento estático é inicializado com zero na inicialização do programa antes de qualquer outra inicialização. Em alguns casos, a inicialização adicional é feita posteriormente.
Eu sempre sugiro que as pessoas desmontem seu código para ver o que o compilador realmente faz com o código C ++. Isso se aplica das classes / duração do armazenamento (como esta pergunta) às otimizações avançadas do compilador. Você pode instruir seu compilador a gerar o assembly, mas existem ferramentas maravilhosas para fazer isso na Internet de maneira amigável. O meu favorito é o GCC Explorer .