Quão importante é inicializar variáveis?
A inicialização adequada evita vazamentos de memória ou tem vantagens de desempenho?
Quão importante é inicializar variáveis?
A inicialização adequada evita vazamentos de memória ou tem vantagens de desempenho?
null
) pelos compiladores comuns, mas são lixo aleatório ao compilar para liberação. (embora meu conhecimento C ++ é de ~ 10 anos atrás, agora, as coisas podem ter mudado)Respostas:
Variáveis não inicializadas tornam um programa não determinístico. Cada vez que o programa é executado, ele pode se comportar de maneira diferente. Mudanças não relacionadas ao ambiente operacional, hora do dia, fase da lua e permutações de tais afetam como e quando esses daemons se manifestam. O programa pode ser executado um milhão de vezes antes que o defeito seja apresentado, ele pode ser executado toda vez ou executar outro milhão. Muitos problemas são atribuídos a "falhas" e ignorados ou relatórios de defeitos de clientes fechados como "Improdutíveis". Com que frequência você reinicializou uma máquina para 'consertar' um problema? Quantas vezes você disse a um cliente "Nunca vi isso acontecer, deixe-me saber se você o vê novamente" - esperando (sabendo) muito bem que eles não vão!
Como a reprodução de um defeito pode ser quase impossível no ambiente de teste, é quase impossível encontrar e corrigir.
Pode levar anos para que o bug apareça, geralmente no código considerado confiável e estável. Presume-se que o defeito esteja no código mais recente - localizá-lo pode demorar significativamente mais. Uma mudança no compilador, uma opção de compilador, até a adição de uma linha de código pode alterar o comportamento.
A inicialização de variáveis tem uma enorme vantagem de desempenho, não apenas porque um programa que funciona corretamente é infinito mais rápido que um que não funciona, mas os desenvolvedores passam menos tempo localizando e corrigindo defeitos que não deveriam estar lá e mais tempo realizando um trabalho "real".
A outra vantagem significativa de inicializar variáveis é que o autor original do código deve decidir o que inicializar. Isso nem sempre é um exercício trivial e, quando não é trivial, pode ser uma indicação de um design inadequado.
O vazamento de memória é um problema diferente, mas a inicialização adequada pode não apenas ajudar na prevenção, mas também na detecção e localização da fonte - é altamente dependente da linguagem e é realmente uma pergunta separada, digna de uma exploração mais aprofundada do que eu posso dar nesta resposta.
Editar: Em alguns idiomas (por exemplo, C #), não é possível usar variáveis não inicializadas, pois o programa não compila ou relata um erro quando executado, se feito. No entanto, muitas linguagens com essas características possuem interfaces para códigos potencialmente inseguros, portanto, é necessário ter cuidado ao usar essas interfaces no para introduzir variáveis não inicializadas.
fonte
A inicialização de uma variável como Telastyn apontou pode evitar bugs. Se a variável for um tipo de referência, a inicialização poderá impedir erros de referência nulos na linha.
Uma variável de qualquer tipo que tenha um padrão não nulo ocupará alguma memória para armazenar o valor padrão.
fonte
Tentar usar uma variável não inicializada é sempre um erro, por isso faz sentido minimizar a probabilidade de ocorrência desse erro.
Provavelmente, a abordagem de linguagem de programação mais comum para atenuar o problema é inicializar automaticamente com um valor padrão; portanto, pelo menos se você esquecer de inicializar uma variável, será algo como, em
0
vez de algo como0x16615c4b
.Isso resolve uma grande porcentagem de erros, se você precisar de uma variável inicializada como zero de qualquer maneira. No entanto, usar uma variável que foi inicializada com um valor incorreto é tão ruim quanto usar uma variável que não foi inicializada. De fato, às vezes pode ser ainda pior, porque o erro pode ser mais sutil e difícil de detectar.
As linguagens de programação funcional resolvem esse problema não apenas desautorizando valores não inicializados, mas desautorizando completamente a reatribuição. Isso elimina o problema e acaba não sendo uma restrição tão severa quanto você imagina. Mesmo em linguagens não funcionais, se você esperar para declarar uma variável até ter um valor correto para inicializá-la, seu código tende a ser muito mais robusto.
Quanto ao desempenho, provavelmente é insignificante. Na pior das hipóteses, com variáveis não inicializadas, você tem uma atribuição extra e amarra alguma memória por mais tempo do que o necessário. Bons compiladores podem otimizar as diferenças em muitos casos.
Vazamentos de memória são completamente independentes, embora as variáveis inicializadas corretamente tendam a estar no escopo por um período mais curto de tempo e, portanto, podem ser um pouco menos propensas a um programador vazar acidentalmente.
fonte
Inicializar implica que o valor inicial é importante. Se o valor inicial importa, então sim, claramente você deve se certificar de que foi inicializado. Se não importa, isso implica que será inicializado mais tarde.
Inicialização desnecessária causa desperdício de ciclos da CPU. Embora esses ciclos desperdiçados possam não ter importância em determinados programas, em outros, cada ciclo é importante, pois a velocidade é a principal preocupação. Portanto, é muito importante entender quais são os objetivos de desempenho e se as variáveis precisam ser inicializadas ou não.
Vazamentos de memória são um problema completamente diferente, que normalmente envolve uma função de alocador de memória para emitir e posteriormente reciclar blocos de memória. Pense em uma agência postal. Você pede uma caixa de correio. Eles te dão um. Você pede outro. Eles te dão outro. A regra é que, quando você terminar de usar uma caixa de correio, precisará devolvê-la. Se você esquecer de devolvê-lo, eles ainda acharão que o possui e a caixa não poderá ser reutilizada por mais ninguém. Portanto, há um pedaço de memória amarrado e não sendo usado, e é isso que é chamado de vazamento de memória. Se você continuar pedindo caixas em algum momento, ficará sem memória. Eu simplifiquei demais isso, mas essa é a ideia básica.
fonte
Como outros disseram, isso depende do idioma. Mas vou demonstrar minhas idéias Java (e Java efetivo) sobre como inicializar variáveis. Estes devem ser utilizáveis para muitos outros idiomas de nível superior.
Constantes e variáveis de classe
Variáveis de classe - marcadas com
static
em Java - são como constantes. Essas variáveis normalmente devem ser finais e inicializadas diretamente após a definição, usando=
ou de dentro de um bloco inicializador de classestatic { // initialize here }
.Campos
Como em muitos idiomas de nível superior e nos campos de script, será automaticamente atribuído um valor padrão. Para números e
char
este será o valor zero. Para Strings e outros objetos, seránull
. Agoranull
é perigoso e deve ser usado com moderação. Portanto, esses campos devem ser configurados com um valor válido o mais rápido possível. O construtor é normalmente um lugar perfeito para isso. Para garantir que as variáveis sejam definidas durante o construtor e não sejam alteradas posteriormente, você pode marcá-las com afinal
palavra - chaveTente resistir ao desejo de usar
null
como algum tipo de bandeira ou valor especial. É melhor, por exemplo, incluir um campo específico para manter o estado. Um campo com o nomestate
que usa os valores de umaState
enumeração seria uma boa opção.Parâmetros do método
Como as alterações nos valores dos parâmetros (sejam referências a objetos ou tipos básicos como números inteiros etc.) não serão vistas pelo chamador, os parâmetros devem ser marcados como
final
. Isso significa que os valores da variável em si não podem ser alterados. Observe que o valor de instâncias de objetos mutáveis pode ser alterado, a referência não pode ser alterada para apontar para um objeto diferente ou, nonull
entanto.Variáveis locais
Variáveis locais não são inicializadas automaticamente; eles precisam ser inicializados antes que seu valor possa ser usado. Um método para garantir que sua variável seja inicializada é inicializá-la diretamente para algum tipo de valor padrão. No entanto, isso é algo que você não deve fazer. Na maioria das vezes, o valor padrão não é o que você esperaria.
É muito melhor definir apenas a variável exatamente onde você precisa da variável. Se a variável tiver apenas um valor único (o que é verdadeiro para a maioria das variáveis em bom código), você poderá marcar a variável
final
. Isso garante que a variável local seja atribuída exatamente uma vez, não zero ou duas vezes. Um exemplo:Observe que muitos idiomas o alertarão se uma variável permanecer não inicializada antes do uso. Verifique as especificações de idioma e os fóruns para ver se você não se preocupa desnecessariamente.
fonte
Não há problema com variáveis não inicializadas.
O problema é apenas quando você lê uma variável que ainda não foi gravada.
Dependendo do compilador e / ou do tipo de variável, a inicialização é realizada na inicialização do aplicativo. Ou não.
É de uso comum não confiar na inicialização automática.
fonte
A inicialização de variáveis (implícita ou explicitamente) é crucial. Não inicializar uma variável é sempre um erro (elas podem ser inicializadas implicitamente, no entanto. Veja abaixo). Compliers modernos como o compilador C # (como exemplo) tratam isso como um erro e não permitem executar o código. Uma variável não inicializada é simplesmente inútil e prejudicial. A menos que você esteja criando um gerador de números aleatórios, você espera que um pedaço de código produza um resultado determinístico e reprodutível. Isso só pode ser alcançado se você começar a trabalhar com variáveis inicializadas.
A questão realmente interessante é se uma variável é inicializada automaticamente ou se você deve fazê-lo manualmente. Depende do idioma usado. Em C #, por exemplo, os campos, ou seja, "variáveis" no nível da classe, são sempre automaticamente inicializados com o valor padrão para esse tipo de variável
default(T)
. Este valor corresponde a um padrão de bits que consiste em todos os zeros. Isso faz parte da especificação da linguagem e não apenas um detalhe técnico da implementação da linguagem. Portanto, você pode confiar nele com segurança. É seguro não inicializar uma variável explicitamente se (e somente se) a especificação da linguagem declarar que foi inicializada implicitamente.Se você deseja outro valor, deve inicializar a variável explicitamente. Contudo; em C # variáveis locais, ou seja, variáveis declaradas em métodos, não são inicializadas automaticamente e você sempre deve inicializar a variável explicitamente.fonte