[C++ - Variaveis Globais] - porque devemos evitar variavies globais?

Cambalinho

Power Member
porque dizem que devemos evitar variaveis globais?
por exemplo: em jogos, sei que tenho de usar variavies globais para nao ter que carregar as imagens de novo e mudanças deposiçoes outras situaçoes. entao porque devemos evitar em as usar?
 
Por estás muito mais sujeito a cometer erros sem reparar (sincronização entre threads por exemplo). Chama-lhe programação defensiva se quiseres.
Tens de ver se o risco suplanta a vantagem de usar a variável como global.
Não sei se será só isto, mas foi sempre assim que vi esta situação.
Boa pergunta, também estou curiosos para ver as respostas do pessoal mais veterano porque não sei se terá algum tipo de implicações em termos de memória.
 
Última edição:
Por estás muito mais sujeito a cometer erros sem reparar (sincronização entre threads por exemplo). Chama-lhe programação defensiva se quiseres.
Tens de ver se o risco suplanta a vantagem de usar a variável como global.
Não sei se será só isto, mas foi sempre assim que vi esta situação.
Boa pergunta, também estou curiosos para ver as respostas do pessoal mais veterano porque não sei se terá algum tipo de implicações em termos de memória.
;)
 
Em teoria, as funções devem ser auto-contidas e manter a transparência referencial, ou seja, produzir o mesmo resultado para um mesmo input (sem efeitos laterais como a alteração de variáveis que não tenham sido explicitamente passadas à função). Se a função depende de uma variável global, então é impossível garantir seja o que for sobre o seu comportamento, porque isso depende das garantias que tivermos acerca da imutabilidade do valor da variável global (tipicamente, são completamente mutáveis).

Resultado: uma mesma função pode funcionar perfeitamente num dado instante e logo de seguida falhar completamente pura e simplesmente porque outra função qualquer que não conhecemos alterou o valor da variável global da qual dependemos. E como ninguém nos avisa que vai alterar um valor global... ficamos às escuras.

Testar o código é também muito mais difícil se este não puder ser isolado facilmente. Utilizar variáveis globais é dar mais um passo no sentido de não conseguir testar o código.

As implicações a nível de memória não me parecem importantes no contexto de alguém que está a dar os primeiros passos na programação.
 
Em teoria, as funções devem ser auto-contidas e manter a transparência referencial, ou seja, produzir o mesmo resultado para um mesmo input (sem efeitos laterais como a alteração de variáveis que não tenham sido explicitamente passadas à função). Se a função depende de uma variável global, então é impossível garantir seja o que for sobre o seu comportamento, porque isso depende das garantias que tivermos acerca da imutabilidade do valor da variável global (tipicamente, são completamente mutáveis).

Resultado: uma mesma função pode funcionar perfeitamente num dado instante e logo de seguida falhar completamente pura e simplesmente porque outra função qualquer que não conhecemos alterou o valor da variável global da qual dependemos. E como ninguém nos avisa que vai alterar um valor global... ficamos às escuras.

Testar o código é também muito mais difícil se este não puder ser isolado facilmente. Utilizar variáveis globais é dar mais um passo no sentido de não conseguir testar o código.

As implicações a nível de memória não me parecem importantes no contexto de alguém que está a dar os primeiros passos na programação.
entao imagina o meu exemplo: tenho 1 jogo com varias variaveis do tipo Sprite(a minha class). entao achas que nao deveria meter estas variaveis globais? se nao as meter globais nao posso fazer 1 programaçao estruturada(programa dividido por varias funçoes):(
neste caso estou a falar de variaveis que controis dentro do mesmo ficheiro fonte(fora das funçoes). apesar de saber que posso construir variaveis dentro doutro ficheiro fonte e as usar.
mas voltando ao meu exemplo: como posso fazer para evitar variaveis globais se estao dependentes das funçoes(mesmo que nao tenham parametros)?
 
Última edição:
Podes, fazes uma classe onde guardas todas as Sprites, e que as percorre sempre que necessário.

Variáveis globais nunca. É mais fácil pensares que elas não existem.
 
Podes, fazes uma classe onde guardas todas as Sprites, e que as percorre sempre que necessário.

Variáveis globais nunca. É mais fácil pensares que elas não existem.

ja obtive 1 2ª opiniao. posso usar as variaveis dentro do main()\reset() e usar ponteiros como argumentos nas outras funçoes;)
 
Exactamente, tens que as passar explicitamente à função que as vai usar (neste caso com apontadores). Ou então reformulas o teu programa, se vires que dá para incorporar essas funções como métodos da classe.
 
Exactamente, tens que as passar explicitamente à função que as vai usar (neste caso com apontadores). Ou então reformulas o teu programa, se vires que dá para incorporar essas funções como métodos da classe.
pois mas se nao fazer as variaveis globais nao posso usar os metodos da class assim(penso eu)
 
Exacto.
Podes criar, por exemplo uma class chamada SpriteManager. Essa classe será a responsável por gerir todas as classes do tipo Sprite, vai ser uma blackbox para o resto do programa lidar com as sprites. Podes depois ter métodos nessa classe que fazem coisas a todos os sprites (por exemplo, um drawAll), métodos que te permitam obter as entidades, etc.

As variáveis globais são, como já se disse aqui, de evitar. São variáveis onde toda a gente pode mexer a belo prazer, o que pode dar origem a maus resultados. Um caso prático: imagina que tu, numa função tens uma variável com um nome muito parecido com o nome de uma das variáveis globais. Por azar, no meio da função enganaste mesmo a escrever o nome e, ao invés de fazeres referência à tua variável local fazes à variável global e alteras-a para um valor que não faz sentido. Os resultados vão ser estranhos e vais andar muito tempo às voltas do código a tentar perceber o que aconteceu. Tempo perdido.
 
Claro. Eu só uso variáveis globais quando estou a fazer uns pequenos programas para a faculdade em C por exemplo. Sei lá, por exemplo utilizar várias threads para fazer algo num vector. Obviamente que com a devida atenção para não aceder ao vector ao mesmo tempo em mais do que uma thread (quando estou a escrever para lá). De resto em C++ , Java , etc , tenho por hábito ter tudo organizado por classes.
 
Mas estás a desenvolver orientado a objectos? Não indicaste isso na tua pergunta original e a resposta correcta depende obviamente do paradigma que estás a usar.

De modo geral, não há qualquer problema em usar variáveis globais quando estás a desenvolver, por exemplo, um programa puramente procedimental. Tens é que mudar ligeiramente a forma como estruturas o programa na tua cabeça e ter consciência que as tuas invariantes (como o pwseo referiu) têm que passar a incluir as variáveis globais que utilizas. No fundo é bastante semelhante a usar-se Singletons quando estamos a desenvolver orientado a objectos; não são muito mais do que variáveis globais.

Infelizmente muitos professores não conseguem perceber a diferença entre "nunca usar variáveis globais" e "as variáveis globais devem ser utilizadas só nos casos adequados", ou então percebem mas usam só a primeira nos cursos introdutórios para simplificar o ensino a quem está a começar e depois este erro é repetido até à exaustão mais tarde.
É muito melhor usar uma variável global do que, por exemplo, ter que passar um apontador em todas as funções. Não há qualquer vantagem ao usar o apontador e o código fica muito mais difícil de ler.
 
Mas estás a desenvolver orientado a objectos? Não indicaste isso na tua pergunta original e a resposta correcta depende obviamente do paradigma que estás a usar.

De modo geral, não há qualquer problema em usar variáveis globais quando estás a desenvolver, por exemplo, um programa puramente procedimental. Tens é que mudar ligeiramente a forma como estruturas o programa na tua cabeça e ter consciência que as tuas invariantes (como o pwseo referiu) têm que passar a incluir as variáveis globais que utilizas. No fundo é bastante semelhante a usar-se Singletons quando estamos a desenvolver orientado a objectos; não são muito mais do que variáveis globais.

Infelizmente muitos professores não conseguem perceber a diferença entre "nunca usar variáveis globais" e "as variáveis globais devem ser utilizadas só nos casos adequados", ou então percebem mas usam só a primeira nos cursos introdutórios para simplificar o ensino a quem está a começar e depois este erro é repetido até à exaustão mais tarde.
É muito melhor usar uma variável global do que, por exemplo, ter que passar um apontador em todas as funções. Não há qualquer vantagem ao usar o apontador e o código fica muito mais difícil de ler.

o meu jogo funciona perfeitamente. com variaveis globais. pois, neste caso, se nao meto as variaveis(sprites\double buffer\e talvez outras), tenho mais dificuldade em estruturar o programa\jogo:(
obrigado pela dica
 
Atenção que não disse que no teu caso devias usar variáveis globais, é impossível dizer isso sem saber a linguagem/paradigma e a arquitectura da aplicação. Só não acho que deves querer removê-las só pelo facto de serem globais.
 
o meu jogo funciona perfeitamente. com variaveis globais. pois, neste caso, se nao meto as variaveis(sprites\double buffer\e talvez outras), tenho mais dificuldade em estruturar o programa\jogo:(
obrigado pela dica


Eu não sei qual é o teu interesse na programação. No entanto se planeias entrar por um caminho mais profissional, não queres apenas que as coisas funcionem, queres que sejam bem estruturadas, que se comportem de forma previsível e que sejam fáceis de manter. Uma das muitas coisas a ter em conta é não usar variáveis globais.

Se tu dizes que não consegues não as usar, então é porque o teu desenho tá errado e conseguiria-se reorganizar isso de uma forma melhor que não as usava.

Óbvio que se estas a aprender pela piada podes perfeitamente deixar assim :)
 
Eu não sei qual é o teu interesse na programação. No entanto se planeias entrar por um caminho mais profissional, não queres apenas que as coisas funcionem, queres que sejam bem estruturadas, que se comportem de forma previsível e que sejam fáceis de manter. Uma das muitas coisas a ter em conta é não usar variáveis globais.

Se tu dizes que não consegues não as usar, então é porque o teu desenho tá errado e conseguiria-se reorganizar isso de uma forma melhor que não as usava.

Óbvio que se estas a aprender pela piada podes perfeitamente deixar assim :)

Não concordo com a segunda parte desta opinião - sem saber detalhes, não existe garantia que os objectivos da primeira parte sejam melhor cumpridos com ou sem a existência de variáveis globais. Na minha opinião, dizer "Se tu dizes que não consegues não as usar, então é porque o teu desenho tá errado e conseguiria-se reorganizar isso de uma forma melhor que não as usava." é uma generalização perigosa e muitas vezes errada. Consigo dar N exemplos de programas muito simples em que usar variáveis globais é a melhor solução, cada caso é um caso. Por exemplo, elaborar um programa em C que leia um conjunto de números (N < 10000000) e os ordene - a solução mais simples de implementar, melhor estruturada, mais previsível e mais fácil de manter envolve um array numa variável global.

Concordo que quem está a iniciar muitas vezes usa variáveis globais quando não deve, mas acho mais importante as alternativas e porque motivo são melhores do que simplesmente dizer "nunca usar".
 
Back
Topo