Entendendo o que extern faz na prática
O extern em C e C++ é uma declaração de ligação (linkage). Ele simplesmente diz ao compilador: "não crie uma nova variável aqui, ela existe em algum outro arquivo de tradução." Isso é tudo. A confusão entre externo é dentro ou fora geralmente nasce porque programadores iniciantes associam a palavra à ideia de "fora do arquivo", mas na verdade o comportamento correto depende de como a variável foi definida originalmente.
externo é dentro ou fora: a resposta curta
A variável declarada com extern pode estar em qualquer arquivo que será linkado juntos. Ela não precisa estar no mesmo arquivo onde você declara extern. A ligação é resolvida pelo linker, não pelo pré-processador. Se o linker não encontrar a definição real, vai dar erro de símbolo não encontrado. Já se duas definições forem encontradas, vai dar erro de múltipla definição.
Como usar corretamente
Crie um arquivo de cabeçalho (header) que contenha apenas a declaração extern, nunca a definição. No arquivo .c ou .cpp onde a variável realmente vive, defina-a normalmente sem extern. Isso é o padrão que funciona. A maioria dos projetos grandes segue essa convenção porque evita definições duplicadas durante o linkage. Eu já perdi meia manhã depurando um erro de múltipla definição porque coloquei a definição de uma variável global diretamente no arquivo de cabeçalho. Qualquer unidade de tradução que incluísse esse header criava sua própria cópia. O compilador não reclamava em tempo algum. Só o linker reportava o erro. Desde aí, faço questão de separar declaração e definição de forma clara e documentada.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Erros comuns que acontecem todo dia
Muita gente põe extern em arquivos .c junto com a definição completa da variável. O código compila sem aviso, mas o comportamento fica estranho porque o linker trata como múltiplas definições. Outro erro clássico é tentar usar extern para variáveis estáticas (static). Variáveis estáticas têm linkage interno por definição e não podem ser acessadas via extern de outro arquivo. Essas duas situações aparecem com frequência em revisões de código e costumam causar travamento de build por horas.
Alternativas quando extern não resolve
Se o seu projeto está ficando complicado demais com variáveis globais declaradas extern, considere usar uma função getter/setter em um módulo dedicado. Esse padrão encapsula o acesso e elimina a necessidade de declarar múltiplos extern. Em projetos C++ modernos, namespaces e templates também reduzem a dependência de variáveis globais quase completamente. O custo de desenvolvimento inicial é maior, mas a manutenção futura costuma compensar. Existem cenários onde extern simplesmente não funciona bem. Por exemplo, variáveis thread-local (thread_local) têm comportamento diferente de linkage e não se encaixam no modelo tradicional de declaração externa. Da mesma forma, objetos C++ com construtores complexos declarados extern podem apresentar problemas de inicialização de ordem entre unidades de tradução. Nesses casos, o modelo de linkage convencional não se aplica e é necessário mudar de estratégia.
Dica rápida de depuração
Se o linker reclama de símbolo não encontrado, verifique primeiro se o arquivo onde a variável foi definida está incluso na lista de fontes da compilação. Muitas vezes o problema não é a declaração extern em si, mas o arquivo conter simplesmente a variável que falta. Verificar o makefile ou a configuração do build economiza mais tempo do que procurar sintaxe errada no código-fonte.