Pergunta

Eu quero saber por que exatamente variáveis ??estáticas em C, C ++ e Java são inicializados por zero por padrão? E por isso não é verdade para as variáveis ??locais?

Foi útil?

Solução

Por que as variáveis ??estáticas são deterministically inicializado e variáveis ??locais não são?

Veja como as variáveis ??estáticas são implementadas. A memória deles é alocado em tempo de ligação, e o valor inicial para eles também é fornecido em tempo de ligação. Não há sobrecarga de tempo de execução.

Por outro lado, a memória para as variáveis ??locais é alocado em tempo de execução. A pilha tem que crescer. Você não sabe o que havia antes. Se você quiser, você pode limpar a memória (zero), mas que seria incorrer em uma sobrecarga de tempo de execução. A C ++ filosofia é "você não pagar por coisas que você não usa", por isso não faz de zero que a memória por padrão.

OK, mas porque são variáveis ??estáticas inicializado para zero, e não algum outro valor?

Bem, você geralmente querem fazer algo com essa variável. Mas, então, como você sabe se ele foi inicializado? Você poderia criar uma variável booleana estática. Mas então ele também tem de ser inicializado de forma confiável a algo (de preferência false). Que tal um ponteiro? Você prefere quer inicializado para NULL que algum lixo aleatório. Como cerca de um struct / record? Tem alguns outros membros de dados dentro. Faz sentido para inicializar todos eles para seus valores padrão. Mas, para simplificar, se você usar a estratégia "Inicializar a 0", você não tem que inspecionar os membros individuais e verificar seus tipos. Você só pode inicializar a área de memória toda a 0.

Isto não é realmente uma exigência técnica. A semântica de inicialização ainda poderia ser considerada sã se o valor padrão é algo diferente de 0, mas ainda determinista. Mas então, o que deve esse valor ser? Você pode muito facilmente explicar por que 0 é utilizado (embora, na verdade parece um pouco arbitrária), mas explicando -1 ou 1024 parece ser ainda mais difícil (especialmente que a variável pode não ser grande o suficiente para manter esse valor, etc).

E você sempre pode inicializar a variável explicitamente.

E você sempre tem parágrafo 8.5.6 do C ++ padrão que diz: "Cada objeto de duração de armazenagem estática deve ser zero-inicializado na inicialização do programa".

Para obter mais informações, consulte a estas outras questões:

Outras dicas

Parágrafo 8.5.6 do C ++ estados padrão que:

"Cada objeto de duração de armazenamento estático será inicializado para zero no início do programa"

(A norma também diz que a inicialização de variáveis ??locais é indefinido)

Quanto ao porquê, o padrão não diz;). Um palpite é que é razoavelmente fácil de implementar, sem quaisquer desvantagens adicionais

Falando para Java:

variáveis ??locais devem ser inicializados antes que você possa acessá-lo, porque é um ganho de segurança. O compilador verifica para você, se a variável é definitivamente definido.

estática ou variáveis ??de classe (com um tipo de objeto) são inicializados com null, porque o compilador não pode verificar se eles são inicializados em tempo de compilação. Em vez de deixar o programa falhar se ele acessa uma variável não inicializada, ele será inicializado implícito com null.

As variáveis ??com um tipo nativo não é possível obter um valor null, portanto as variáveis ??não-locais são inicializados com 0 ou false, como um fallback. Não é melhor solução, claro, mas eu não sei um melhor. ; -)

Assim, em certa medida, estas são decisões de design apenas por parte dos projetistas da linguagem. Mas as razões prováveis ??para essas decisões em Java são:

  • para variáveis ??static / membros, se você estiver indo para inicializar-los para alguma coisa, então zero é um valor conveniente, porque (a) geralmente é um valor adequado para significar "não definida para qualquer outra coisa especial", e é o valor você teria escolhido qualquer maneira, em alguns casos, tais como contadores; e (b) internamente, é provável que zero pode ser usado para valores "especiais", nomeadamente para representar nulo no caso de uma referência de objeto.
  • para as variáveis ??locais, dando-lhes nenhum padrão permite a regra de que as forças do programador para definir algum valor antes da variável é lido, o que pode ser realmente útil em permitir que o compilador para detectar certos erros.

No caso das variáveis ??locais, também é concebível que uma variável local pode ser declarada (que no nível do bytecode código / máquina essencialmente significa alocar espaço de pilha / mover o ponteiro da pilha), mas depois nunca realmente escrito / lido em um determinado caminho de código. Então, não ter um padrão evita fazendo trabalho desnecessário de definir um padrão nesses casos.

Repito, no entanto, estas são decisões de design em certa medida. Eles são essencialmente uma troca entre o que é provável que seja conveniente para implementações de JVM e conveniente para programadores.

NB. Em C / C ++, variáveis ??"estáticas" significa uma coisa diferente para variáveis ??estáticas no Java!

Eu não tenho nenhuma idéia sobre java e eu duvido que seja diferente para estática / locais em java.

Como para C e C ++, é sobre os programadores se preocupar com seu efeito de código e amando estar no controle. Inicializar variáveis ??locais implicaria execução de código extra cada programa de tempo entra no escopo. Para freqüentemente chamados funções que podem ser um desastre.

Isso tem a ver com o conceito de "só paga pelo que você usa" em C / C ++.

Para variáveis ??estáticas, uma inicialização pode ser feita sem gerar código. O arquivo objeto contém os valores iniciais para as variáveis ??no segmento de dados e quando as cargas do sistema operacional os executáveis ??ele carrega e mapeia esse segmento de dados antes de o programa começa a execução.

Para variáveis ??locais não há nenhuma maneira para inicializar-los sem código, porque eles não são inicializados uma vez, eles devem ser inicializado toda vez que você entrar no seu âmbito; Também eles são alocados na pilha, e quando a alocação ocorre o valor inicial na pilha no caso geral é simplesmente o que estava lá antes (exceto aqueles momentos raros que você crescer a pilha mais do que cresceu antes).

Assim, para inicializar implicitamente uma variável local o compilador precisa gerar código sem o programador comandar explicitamente a fazê-lo, o que é bastante contra essa "filosofia".

Sobre Java, tanto quanto eu sei, as variáveis ??são sempre inicializados quando o programa entra em seu escopo, não importa se eles são estáticos ou não. A única diferença significativa entre eles é que o escopo de variáveis ??estáticas é todo o programa. Dado que, o comportamento é consistente entre todos eles.

Este é apenas um palpite, mas pode ser do jeito que é para estática, já que é fácil de implementar, e útil.

O compilador pode co-alocar todas as variáveis ??em uma área contigous memória e código de então ou emitem (uma única chamada memset()) para limpá-la antes main() é chamado. Em muitos casos, também pode contar com recursos do formato de arquivo executável do sistema operacional, se esse formato suportes " bss seções ", que são apuradas pelo carregador vez. Isso economiza espaço no executável, você poderia ter

static unsigned char megabyte[1 << 20];

eo executável não iria crescer por um megabyte.

Para variáveis ??locais, nenhuma destas situações se aplica; eles são alocados "on the fly" (normalmente em uma pilha) e seria um desperdício de recursos para limpá-las, uma vez que eles estão indo normalmente a ser atribuído a muito em breve de qualquer maneira.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top