paulo1205
(usa Ubuntu)
Enviado em 11/03/2015 - 21:46h
mulatinho escreveu:
Nunca use variáveis com nome de funções padrões.
Acho esse “nunca” um pouco forte. Não que eu discorde da ideia de que é bom evitar potenciais conflitos e supreposições de nomes, mas às vezes a gente usa um nome sem nem lembrar (às vezes mesmo sem saber, principalmente, quando existem bibliotecas de terceiros misturas no projeto) da sua existência num outro ponto do programa, e nem por isso dá erro.
Apesar do código que ele mostrou só usar efetivamente recursos do C e de bibliotecas feitas para uso com C, ele menciona C++ no título. O C++ padrão possui o conceito de espaços de nomes (
namespaces) distintos para diferentes símbolos, e operadores que permitem a seleção do namespace de onde se deseja busca o símbolo. Todas as funções, variáveis e classes da biblioteca padrão do C++ ficam no namespace chamado
std. Símbolos globais ficam no namespace global, que não tem um nome próprio, e é nesse namespace global que vão parar os símbolos declarados em arquivos pensados para uso com C (o C++ oferece reimplementações de alguns cabeçalhos da biblioteca padrão do C que copiam os símbolos do namespace global para o
std). Ainda, quando se quer ter um símbolo visível somente dentro de um arquivo de código fonte (o que se faz em C colocando a especificação
static no tipo da variável que de outro modo seria global), a abordagem do C++ é usar um namespace anônimo.
Se o programa do nosso amigo realmente está em C++, ele poderia manter a variável local com o nome
bind, e usar o operador de seleção de namespace
:: para ter acesso ao símbolo global.
Veja o seguinte exemplo, que espero que ajude a clarear o que eu quis dizer.
#include <cstdio> // A versão C++ de stdio.h, que copia nomes para dentro de std.
void func(){
// Exemplo horroroso: por que alguém chamaria uma
// variável local inteira de "printf"? Só mesmo para
// ilustrar um ponto...
int printf=5;
// Usa printf() global para imprimir valor de printf local.
::printf("%d\n", printf);
// Mesma coisa, usando a cópia importada para dentro de std.
std::printf("%d\n", printf);
}
Outra ilustração.
// Este é o arquivo file.cpp
#include <cstdio>
int ivar=10; // Variável no namespace global.
namespace ns {
int ivar=20; // Variável no namespace ns.
}
namespace {
int ivar=30; // Variável num namespace anonimo; só é visível dentro de file.cpp
int othervar=40; // Outra variável no namespace anônim; só é visível dentro de file.cpp
// Função no namespace anônimo; só é visível dentro de file.cpp
int get_ivar(){
return ivar;
}
}
void f(){
int ivar=50;
int othervar=60;
printf("ivar=%d\n", ivar); // imprime 50, ivar local
printf("othervar=%d\n", othervar); // imprime 60, othervar local
printf("ns::ivar=%d\n", ns::ivar); // imprime 20, especificação explícita
printf("::ivar=%d\n", ::ivar); // imprime 10: global tem pioridade sobre anônimo
printf("::othervar=%d\n", ::othervar); // imprime 40, othervar do anônimo
printf("get_ivar()=%d\n", get_ivar()); // imprime 30, get_ivar usa ivar do mesmo namespace
{
using ::ivar;
printf("ivar=%d\n", ivar); // imprime 10, ivar global por força de ‘using’
}
{
using ns::ivar;
printf("ivar=%d\n", ivar); // imprime 20, ivar de ns por força de ‘using’
}
}