Erros comuns do compilador¶
Uma coletânea das mensagens de erro mais frequentes do curso, com o que elas realmente significam e como resolver. Se você travou num erro, procure aqui antes de pedir ajuda — boa parte já está catalogada.
Erros de compilação (o g++ recusa gerar o executável)¶
error: ‘X’ was not declared in this scope¶
Você usou um nome (std::cout, std::string, uma função sua) que o compilador não conhece nesse ponto. Causas mais comuns:
- Faltou
#include(ex.:<iostream>parastd::cout,<string>parastd::string,<vector>parastd::vector). - Faltou o prefixo
std::e você não temusing namespace std;. - Você está chamando uma função antes de declará-la (em C++, diferente de algumas linguagens, o compilador processa o arquivo de cima para baixo — a declaração precisa vir antes do uso).
- Erro de digitação no nome.
error: expected ‘;’ before ...¶
Falta um ; no fim de alguma linha antes da apontada pelo erro — o compilador só percebe o problema quando já leu além do ponto onde o ; deveria estar. Olhe a linha anterior primeiro.
error: expected ‘}’ at end of input / error: expected declaration before ‘}’ token¶
Chaves {/} desbalanceadas em algum lugar do arquivo — sobrou ou faltou uma. Editores com destaque de chave correspondente (a maioria) ajudam a achar o desbalanceamento.
error: invalid initialization of non-const reference from an rvalue¶
Você tentou passar um valor temporário (uma expressão como 2 + 3, ou o retorno de uma função) para um parâmetro T& (referência não-const). Referência não-const exige uma variável de verdade para se ligar. Se a função só vai ler o valor, mude o parâmetro para const T&.
error: no matching function for call to ...¶
Você chamou uma função/método com argumentos que não batem com nenhuma versão disponível — tipo errado, número errado de argumentos, ou (com sobrecarga) nenhuma versão aceita exatamente essa combinação. A mensagem completa costuma listar as opções disponíveis logo abaixo — compare com o que você passou.
error: use of deleted function ‘X::X()’¶
Você tentou criar um objeto sem argumentos (MinhaClasse obj;), mas a classe só tem construtor(es) que exigem argumentos (e o compilador, por isso, não gera um construtor padrão). Forneça os argumentos exigidos.
error: passing ‘const X’ as ‘this’ argument discards qualifiers¶
Você chamou um método não-const a partir de um objeto/referência const (por exemplo, um parâmetro const MinhaClasse&). Métodos que alteram o objeto não podem ser chamados quando ele está marcado const. Se o método só lê os campos, marque-o como const.
error: cannot declare variable ‘x’ to be of abstract type ‘X’¶
Você tentou criar diretamente um objeto de uma classe abstrata (que tem pelo menos um método virtual puro, = 0). Crie uma classe filha que implemente todos os métodos puros, e instancie a filha.
error: no match for ‘operator[]’ (em map/set const)¶
Você tentou usar [] num map/set que chegou como const (por exemplo, const std::map<...>& m, e m[chave]). operator[] pode inserir uma chave nova, o que alteraria o container — por isso não existe versão const dele. Use .at(chave) (lança exceção se não existir) ou .find(chave)/.count(chave) para leitura seg.
redefinition of class ‘X’ / redefinition of ‘...’¶
Falta um include guard (#ifndef/#define/#endif) no .h, ou ele está mal escrito (nome de macro repetido em dois arquivos diferentes). Veja o capítulo 12.
Erros de linkedição (o g++ compila cada arquivo, mas falha ao juntar tudo)¶
undefined reference to ‘Classe::metodo(...)’¶
Você declarou metodo no .h mas esqueceu de:
- implementá-lo em algum
.cpp, ou - incluir esse
.cppna linha de compilação (g++ main.cpp faltou_esse.cpp -o programa).
Veja o capítulo 12 — é sempre um dos dois.
undefined reference to ‘main’¶
Nenhum dos arquivos compilados tem uma função main(). Confira se você incluiu o arquivo certo na compilação.
Quando um teste falha (Assertion failed)¶
Assertion failed: (expr), function main, file X, line N. (ou similar) e o programa encerra¶
Isso não é um erro de compilação nem um bug do seu programa em si — é o assert() (de <cassert>) usado pelos testes de cada exercício avisando que uma condição esperada deu falsa. X:N diz em qual arquivo e linha o teste parou; expr é a condição exata que falhou (compare com o que sua função deveria devolver ali). O programa para imediatamente nesse ponto — os testes que viriam depois dessa linha nunca chegam a rodar. Corrija a lógica da sua função (nunca a linha do assert em si, que é o teste — não a solução), recompile e rode de novo: se havia mais de um problema, o próximo assert que falhar vai aparecer na vez dele.
Avisos do compilador (o programa compila, mas o g++ reclama)¶
Aviso não é erro: o executável é gerado do mesmo jeito. Mas todo aviso do -Wall -Wextra aponta para algo que o compilador julgou suspeito o bastante para interromper você — trate como defeito a corrigir, não como ruído a ignorar.
warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type'¶
Você comparou um int com o resultado de .size(), que é std::size_t — um tipo sem sinal. Para comparar, o compilador precisa converter um dos lados, e há valores em que essa conversão dá o resultado errado. Duas correções, e a escolha depende do laço (capítulo 4):
- índice que só anda para frente: declare
std::size_t i = 0; - índice que entra em conta que pode ficar negativa (
i - 1,n - passada, percorrer de trás para frente): guardeint n = static_cast<int>(v.size());antes do laço e compare comn.
warning: unused parameter 'x' / unused variable 'x'¶
Você declarou algo que nunca usou — muito comum em stub de exercício ainda não implementado, e nesse caso é esperado. Se não for esse o caso, geralmente indica que você esqueceu de usar o parâmetro que deveria ter usado (ou usou outro no lugar dele por engano).
Comportamento errado sem erro de compilação (os mais perigosos)¶
O programa compila e roda, mas imprime a versão "errada" de um método sobrescrito¶
Falta virtual na classe base. Sem ele, a chamada é resolvida em tempo de compilação pelo tipo da referência/ponteiro, não pelo tipo real do objeto — veja o capítulo 11.
O laço nunca termina, ou lê memória alheia num container vazio¶
Quase sempre é size() sem sinal. Como std::size_t nunca é negativo, num vector vazio v.size() - 1 não dá -1: dá o maior número que cabe no tipo (18446744073709551615 em 64 bits). Assim, for (std::size_t i = 0; i < v.size() - 1; i++) num vector vazio percorre memória que não é sua, e for (std::size_t i = v.size() - 1; i >= 0; i--) não termina nunca, porque i >= 0 é sempre verdadeiro. Em ambos os casos, guarde o tamanho em int n = static_cast<int>(v.size()) antes do laço. Veja o capítulo 4.
"double free or corruption", ou crash aleatório perto do fim do programa¶
Quase sempre cópia rasa de uma classe que gerencia um ponteiro bruto (new/delete manual) sem construtor de cópia customizado. A correção, na maioria dos casos, é a regra do zero: trocar o ponteiro bruto por vector/string/unique_ptr — veja o capítulo 10.
O programa usa cada vez mais memória ao longo do tempo, sem crash imediato¶
Vazamento de memória: algum new sem delete correspondente em algum caminho do código. Ferramentas como -fsanitize=address (compile com essa flag extra) ou Valgrind detectam isso automaticamente.
std::cin >> variavel seguido de std::getline "pula" a leitura¶
>> deixa o \n da tecla Enter no buffer de entrada, e a próxima chamada a std::getline lê essa linha vazia. Se você precisar misturar os dois, descarte o \n restante antes do getline (fora do escopo detalhado deste curso, mas saiba que o problema tem nome).
Comparação de double/float com == às vezes falha "sem motivo"¶
Ponto flutuante tem erro de arredondamento inerente à representação binária. Nunca compare com == — use uma margem de tolerância, como os testes do curso fazem: assert(std::abs(obtido - esperado) <= 0.0001); (precisa de #include <cmath>).