«Undefined reference» — o principal inimigo do iniciante em C++ (e não só)
\n\nVocê escreve o código, tudo parece perfeito, o compilador fica em silêncio, você clica em «Compilar» — e então… uma parede de texto vermelho. O protagonista deste pesadelo é undefined reference (ou unresolved external symbol). Familiar? Se você já escreveu em C++ pelo menos uma vez, certamente já encontrou esse erro. Ele assusta iniciantes, mas na verdade é apenas um sinal: «Eu sei de qual função você está falando, mas não consigo encontrar a implementação dela».
\n\nNeste tutorial, vamos analisar o que é o erro de referência indefinida, por que ele ocorre e, o mais importante — como corrigi-lo. Você aprenderá as 5 causas mais comuns e receberá uma lista de verificação pronta para resolver o problema. Vamos lá!
\n\nO que é undefined reference / unresolved external symbol?
\n\nVamos começar com a teoria, mas bem pouca. O processo de compilação de um programa C++ consiste em duas etapas:
\n- \n
- Compilação — cada arquivo
.cppé transformado em um arquivo objeto (.oou.obj). O compilador verifica a sintaxe e memoriza quais funções foram declaradas (protótipos). \n - Linkagem (ligação) — o linker (ligador) conecta todos os arquivos objeto e bibliotecas em um único arquivo executável. Nesta etapa, ele procura as implementações de todas as funções prometidas. \n
O erro undefined reference (no Visual Studio — unresolved external symbol) ocorre exatamente na etapa de linkagem. O compilador passou com sucesso, mas o linker não encontrou o corpo da função. Ele grita: «Você disse que a função foo() existe, mas não consigo encontrar onde ela está definida!».
Top 5 causas do erro undefined reference em C++
\n\nVamos analisar os cenários mais populares com exemplos reais. Em cada caso, mostrarei o código com erro e a forma de corrigi-lo.
\n\n1. Você declarou, mas não definiu a função
\nClássico. Você escreveu o protótipo da função, mas esqueceu a implementação.
\n// main.cpp\n#include <iostream>\n\nvoid hello(); // declaração (protótipo)\n\nint main() {\n hello();\n return 0;\n}\n// Implementação de hello() está faltando!\n\nErro de linkagem: undefined reference to `hello()'. Correção: escreva o corpo da função.
2. Você não incluiu o arquivo com a implementação na compilação
\nEste é um problema comum ao trabalhar com vários arquivos .cpp. Suponha que você declarou a função em utils.h, definiu em utils.cpp, mas esqueceu de adicionar utils.cpp no comando de compilação.
// utils.h\nvoid printMessage();\n\n// utils.cpp\n#include <iostream>\n#include "utils.h"\nvoid printMessage() {\n std::cout << "Hello!" << std::endl;\n}\n\n// main.cpp\n#include "utils.h"\nint main() {\n printMessage();\n return 0;\n}\n\nSe você compilar apenas main.cpp (g++ main.cpp), o linker não verá utils.cpp. Correção: compile ambos os arquivos juntos: g++ main.cpp utils.cpp -o program.
3. Classe ou template definido no .cpp, e não no .h
\nEsta é uma dor específica do C++. Se você define um método de classe diretamente no arquivo .cpp, mas inclui apenas o cabeçalho, o linker não encontrará a implementação.
// MyClass.h\nclass MyClass {\npublic:\n void doSomething();\n};\n\n// MyClass.cpp\n#include "MyClass.h"\nvoid MyClass::doSomething() { /* ... */ }\n\n// main.cpp\n#include "MyClass.h"\nint main() {\n MyClass obj;\n obj.doSomething(); // Erro: undefined reference\n return 0;\n}\n\nCorreção: certifique-se de que MyClass.cpp está participando da compilação (veja o ponto 2).
4. Linkagem incorreta de bibliotecas (por exemplo, math.h)
\nAlgumas bibliotecas (como a matemática libm) exigem indicação explícita