C++ Lendo Erros do Compilador
Todo programador, do primeiro dia ao vigésimo ano, vê erros de compilação o tempo todo. A diferença é que quem tem experiência lê a mensagem e sabe onde olhar em segundos. As mensagens do g++ estão em inglês e às vezes parecem enormes, mas seguem sempre o mesmo formato e usam um vocabulário pequeno. Nesta aula você aprende a ler esse formato, conhece os erros mais comuns de quem começa, com a mensagem real e a correção, e descobre por que um erro às vezes aparece na linha errada, ou vira centenas de linhas.
- As partes de uma mensagem:
arquivo:linha:coluna: error: mensagem, a linha copiada e o^. - Um método para consertar erros sem se perder.
- As palavras em inglês que mais aparecem.
- Os erros mais comuns:
;faltando,std::faltando,#includefaltando, aspas e chaves, nome errado, tipo errado. - Por que o erro às vezes aparece na linha de baixo.
- Por que um erro só pode gerar dezenas de mensagens, e como achar a que importa.
- A diferença entre erro de compilação e erro de ligação (
undefined reference). - As mesmas mensagens no Clang, o compilador do editor do guia.
Todos os códigos desta aula têm erros de propósito. Eles foram compilados na máquina da Ana com g++ -std=c++23 -Wall -Wextra (g++ 15.2) e, quando indicado, com o clang++ 21.1, numa pasta ~/erros. As mensagens foram copiadas sem mudar nada, inclusive as aspas tipográficas ‘assim’ que o g++ usa. Uma lista maior, para consulta, está em Mensagens de Erro.
A ideia: o corretor ortográfico
Quando você escreve um texto no celular, o corretor sublinha uma palavra em vermelho e sugere outra. Ele não entende o que você quis dizer: só sabe que aquela palavra não existe no dicionário dele. Às vezes a sugestão é perfeita; às vezes é engraçada.
O compilador é um corretor muito mais rígido. Ele lê o seu código do começo ao fim e, quando algo não se encaixa nas regras do C++, anota onde percebeu o problema e o que esperava encontrar. Duas coisas para guardar desde já:
- Um erro de compilação não estraga nada. O programa só não é criado até você consertar. Pode errar à vontade.
- O compilador diz onde percebeu o erro, e isso nem sempre é onde você errou. Você vai ver por quê.
1. Anatomia de uma mensagem
A Ana esqueceu o ponto e vírgula no fim da linha 4:
#include <iostream>
int main() {
std::cout << "Lista de compras\n"
std::cout << "Arroz\n";
}
$ g++ -std=c++23 -Wall -Wextra pv.cpp -o pv
pv.cpp: In function ‘int main()’:
pv.cpp:4:38: error: expected ‘;’ before ‘std’
4 | std::cout << "Lista de compras\n"
| ^
| ;
5 | std::cout << "Arroz\n";
| ~~~
A linha mais importante é a terceira. Ela tem cinco partes, separadas por dois-pontos:
- pv.cpp:
- O arquivo onde está o problema. Em programas com vários arquivos, isso importa muito.
- 4:
- A linha. Os editores mostram o número das linhas na margem; no VS Code, Ctrl + G pula direto para uma linha.
- 38:
- A coluna: em que caractere da linha, contando da esquerda. Na prática, quem mostra a coluna é o
^, logo abaixo. - error:
- O tipo da mensagem.
error= o programa não foi criado. Outros tipos:warning(aviso, o programa é criado),note(nota, uma informação extra sobre a mensagem anterior) efatal error(o compilador nem conseguiu continuar). - expected ‘;’ before ‘std’
- A descrição: "esperava
;antes destd".
E as outras linhas:
| Linha da mensagem | O que é |
|---|---|
pv.cpp: In function ‘int main()’: | Contexto: "na função int main()". Diz em qual função estão os erros que vêm a seguir. |
4 | std::cout << "Lista de compras\n" | A linha 4 do seu código, copiada, para você não precisar procurar. |
| ^ | O acento circunflexo aponta a coluna exata: logo depois das aspas finais. |
| ; | Uma sugestão de correção (fix-it): o g++ desenha o ; onde ele deveria estar. |
5 | std::cout … e ~~~ | A linha 5, com o std sublinhado (~~~): é o "std" da descrição, a primeira coisa que o g++ viu depois do lugar onde faltou o ;. |
Depois de um erro, o programa não é criado, e o g++ termina com o código de saída 1 (aula Olá, Mundo):
$ g++ -std=c++23 -Wall -Wextra pv.cpp -o pv; echo "código de saída: $?"
pv.cpp: In function ‘int main()’:
pv.cpp:4:38: error: expected ‘;’ before ‘std’
4 | std::cout << "Lista de compras\n"
| ^
| ;
5 | std::cout << "Arroz\n";
| ~~~
código de saída: 1
$ ls
pv.cpp « nenhum programa "pv" foi criado
2. O vocabulário das mensagens
Você não precisa saber inglês para ler erros de compilação. Umas vinte palavras resolvem quase tudo:
| Em inglês | Em português | Exemplo |
|---|---|---|
expected | esperava (e não achou) | expected ‘;’ |
before / after | antes de / depois de | before ‘}’ token |
token | "pedaço": cada palavra ou símbolo do código | ‘}’ token |
declared / not declared | declarado (criado) / não declarado | ‘x’ was not declared |
undeclared identifier | nome não declarado (forma do Clang) | use of undeclared identifier 'x' |
scope | escopo: a parte do código onde um nome vale | in this scope |
member of | membro de (algo que mora dentro de) | not a member of ‘std’ |
did you mean | você quis dizer | did you mean ‘cout’? |
missing | faltando | missing terminating " character |
terminating | de fechamento | idem |
at end of input | no fim do arquivo | expected ‘}’ at end of input |
invalid conversion | conversão inválida (tipo errado) | from ‘const char*’ to ‘int’ |
no match for | nenhuma combinação serve para | no match for ‘operator<<’ |
ambiguous | ambíguo: mais de uma opção serve | reference to ‘size’ is ambiguous |
stray | perdido, solto | stray ‘\’ in program |
undefined reference | referência indefinida (erro de ligação) | undefined reference to `main' |
candidate | candidato: uma opção que o compilador tentou | note: candidate 1: … |
In file included from | no arquivo incluído a partir de | o caminho até um cabeçalho da biblioteca |
3. O método: um erro de cada vez
- Leia só o primeiro
error:. Os seguintes podem ser consequência dele. - Vá até a linha e a coluna indicadas.
- Leia a descrição com o vocabulário acima. Se houver
did you meanou uma sugestão desenhada embaixo da linha, considere-a (mas não obedeça cegamente). - Se a linha parece certa, olhe a de cima. Ponto e vírgula, aspas e chaves esquecidos são percebidos depois.
- Corrija só esse erro e compile de novo. Muitas vezes os outros somem junto.
Editores como o VS Code (com a extensão de C++ ou o clangd) sublinham os erros em vermelho enquanto você digita, com a mesma mensagem do compilador ao passar o mouse. Veja Editores e IDEs. Mesmo assim, saber ler a mensagem do terminal é essencial: ela é a palavra final.
4. Os erros mais comuns de quem começa
4.1. Faltou o ponto e vírgula, e o erro aparece na linha de baixo
Você já viu o pv.cpp: o ; faltava na linha 4, e o g++ apontou a linha 4. Mas nem sempre é assim. Aqui o ; falta no fim de uma linha que cria uma variável (variáveis são da aula Variáveis):
#include <iostream>
int main() {
int idade = 29
std::cout << idade << "\n";
}
$ g++ -std=c++23 -Wall -Wextra pv2.cpp -o pv2
pv2.cpp: In function ‘int main()’:
pv2.cpp:5:5: error: expected ‘,’ or ‘;’ before ‘std’
5 | std::cout << idade << "\n";
| ^~~
pv2.cpp:4:9: warning: unused variable ‘idade’ [-Wunused-variable]
4 | int idade = 29
| ^~~~~
O erro está na linha 4, mas o g++ apontou a linha 5, coluna 5. Por quê? Lembre que, para o compilador, a quebra de linha não significa nada (aula Sintaxe). Ele leu int idade = 29 std::cout … como uma coisa só, e só percebeu o problema ao chegar no std, que não tem como continuar a frase. A descrição ajuda: "esperava , ou ; antes de std". Antes do std está o fim da linha 4.
E o aviso de "variável não usada"? É um efeito colateral: como a linha 5 não foi entendida, o compilador acha que a idade nunca foi usada. Consertando o erro, o aviso some.
O Clang, nesse caso, aponta direto para o lugar certo (é por isso que o editor do guia às vezes é mais preciso que o terminal):
$ clang++ -std=c++23 -Wall -Wextra pv2.cpp -o pv2
pv2.cpp:4:19: error: expected ';' at end of declaration
4 | int idade = 29
| ^
| ;
1 error generated.
$ clang++ -std=c++23 -Wall -Wextra pv.cpp -o pv
pv.cpp:4:38: error: expected ';' after expression
4 | std::cout << "Lista de compras\n"
| ^
| ;
1 error generated.
"Esperava ; no fim da declaração" / "depois da expressão". O Clang termina sempre com uma contagem: 1 error generated. ("1 erro gerado").
Correção: o ; no fim da linha de cima da que foi apontada (no g++) ou exatamente onde o ^ indica (no Clang).
4.2. Faltou o std::
#include <iostream>
int main() {
cout << "Olá!\n";
}
$ g++ -std=c++23 -Wall -Wextra semstd.cpp -o semstd
semstd.cpp: In function ‘int main()’:
semstd.cpp:4:5: error: ‘cout’ was not declared in this scope; did you mean ‘std::cout’?
4 | cout << "Olá!\n";
| ^~~~
| std::cout
In file included from semstd.cpp:1:
/usr/include/c++/15/iostream:65:18: note: ‘std::cout’ declared here
65 | extern ostream cout; ///< Linked to standard output
| ^~~~
$ clang++ -std=c++23 -Wall -Wextra semstd.cpp -o semstd
semstd.cpp:4:5: error: use of undeclared identifier 'cout'; did you mean 'std::cout'?
4 | cout << "Olá!\n";
| ^~~~
| std::cout
/usr/lib/gcc/x86_64-linux-gnu/15/../../../../include/c++/15/iostream:65:18: note: 'std::cout' declared here
65 | extern ostream cout; ///< Linked to standard output
| ^
1 error generated.
g++: "cout não foi declarado neste escopo; você quis dizer std::cout?". Clang: "uso de identificador não declarado cout; você quis dizer std::cout?". Mesma ideia, palavras diferentes. A note mostra onde o std::cout de verdade foi declarado, dentro da biblioteca: é só informação, você não precisa mexer lá.
Correção: std::cout (aula Sintaxe).
4.3. Faltou o #include
int main() {
std::cout << "Olá!\n";
}
$ g++ -std=c++23 -Wall -Wextra inc.cpp -o inc
inc.cpp: In function ‘int main()’:
inc.cpp:2:10: error: ‘cout’ is not a member of ‘std’
2 | std::cout << "Olá!\n";
| ^~~~
inc.cpp:1:1: note: ‘std::cout’ is defined in header ‘<iostream>’; this is probably fixable by adding ‘#include <iostream>’
+++ |+#include <iostream>
1 | int main() {
$ clang++ -std=c++23 -Wall -Wextra inc.cpp -o inc
inc.cpp:2:5: error: use of undeclared identifier 'std'
2 | std::cout << "Olá!\n";
| ^
1 error generated.
O g++ é generoso aqui: "cout não é membro de std", e a nota diz "std::cout é definido no cabeçalho <iostream>; provavelmente se resolve acrescentando #include <iostream>". A linha com +++ |+ mostra a linha que ele acrescentaria. O Clang é mais seco: nem o std existe, porque nada da biblioteca foi incluído.
Correção: o #include do cabeçalho certo no topo do arquivo. Cada recurso da biblioteca mora num cabeçalho; as aulas sempre dizem qual.
4.4. Aspas que não fecham
#include <iostream>
int main() {
std::cout << "Olá, Ana!\n;
}
$ g++ -std=c++23 -Wall -Wextra aspas.cpp -o aspas
aspas.cpp:4:18: warning: missing terminating " character
4 | std::cout << "Olá, Ana!\n;
| ^
aspas.cpp:4:18: error: missing terminating " character
4 | std::cout << "Olá, Ana!\n;
| ^~~~~~~~~~~~~
aspas.cpp: In function ‘int main()’:
aspas.cpp:5:1: error: expected primary-expression before ‘}’ token
5 | }
| ^
"Falta o caractere " de fechamento". O ^~~~ sublinha o texto que ficou aberto: das aspas de abertura até o fim da linha. Repare que o ; foi parar dentro do texto, e por isso veio o segundo erro na linha 5. Corrigindo as aspas, ele some.
Correção: feche as aspas: "Olá, Ana!\n";. Os editores pintam o texto de uma cor só até as aspas fecharem, o que ajuda a enxergar.
4.5. Chave faltando ou sobrando
#include <iostream>
int main() {
std::cout << "Olá!\n";
$ g++ -std=c++23 -Wall -Wextra chave.cpp -o chave
chave.cpp: In function ‘int main()’:
chave.cpp:4:27: error: expected ‘}’ at end of input
4 | std::cout << "Olá!\n";
| ^
chave.cpp:3:12: note: to match this ‘{’
3 | int main() {
| ^
"Esperava } no fim da entrada" (no fim do arquivo). A note é a parte útil: "para combinar com esta {", e aponta a chave que ficou aberta. Em programas grandes, a chave que falta pode estar bem longe do fim do arquivo; o recuo bem-feito (aula Sintaxe) é o que permite achá-la.
Com uma chave a mais:
$ g++ -std=c++23 -Wall -Wextra chave2.cpp -o chave2 « a linha 6 tem uma } sobrando
chave2.cpp:6:1: error: expected declaration before ‘}’ token
6 | }
| ^
$ clang++ -std=c++23 -Wall -Wextra chave2.cpp -o chave2
chave2.cpp:6:1: error: extraneous closing brace ('}')
6 | }
| ^
1 error generated.
O g++ diz "esperava uma declaração antes de }"; o Clang é mais direto: "chave de fechamento sobrando".
Correção: toda { tem a sua }. Muitos editores destacam o par quando o cursor está numa chave.
4.6. Nome escrito errado
#include <iostream>
int main() {
int idade = 29;
std::cout << idadi << "\n";
std::cot << "Fim\n";
}
$ g++ -std=c++23 -Wall -Wextra nome.cpp -o nome
nome.cpp: In function ‘int main()’:
nome.cpp:5:18: error: ‘idadi’ was not declared in this scope; did you mean ‘idade’?
5 | std::cout << idadi << "\n";
| ^~~~~
| idade
nome.cpp:6:10: error: ‘cot’ is not a member of ‘std’; did you mean ‘oct’?
6 | std::cot << "Fim\n";
| ^~~
| oct
nome.cpp:4:9: warning: unused variable ‘idade’ [-Wunused-variable]
4 | int idade = 29;
| ^~~~~
Dois erros independentes (aqui, sim, vale a pena ler os dois). O primeiro tem a sugestão certa: idadi → idade. O segundo mostra que o compilador chuta: para cot, ele sugeriu oct (uma coisa que existe na biblioteca, para mostrar números em base 8), e não o cout que você queria. O Clang acertou este:
$ clang++ -std=c++23 -Wall -Wextra nome.cpp -o nome 2>&1 | grep error nome.cpp:5:18: error: use of undeclared identifier 'idadi'; did you mean 'idade'? nome.cpp:6:10: error: no member named 'cot' in namespace 'std'; did you mean 'cout'? 2 errors generated.
Correção: o nome exato, com as mesmas maiúsculas. Use a sugestão como pista, não como ordem.
4.7. Tipo errado
#include <iostream>
int main() {
int idade = "vinte e nove";
std::cout << idade << "\n";
}
$ g++ -std=c++23 -Wall -Wextra tipo.cpp -o tipo
tipo.cpp: In function ‘int main()’:
tipo.cpp:4:17: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
4 | int idade = "vinte e nove";
| ^~~~~~~~~~~~~~
| |
| const char*
$ clang++ -std=c++23 -Wall -Wextra tipo.cpp -o tipo
tipo.cpp:4:9: error: cannot initialize a variable of type 'int' with an lvalue of type 'const char[13]'
4 | int idade = "vinte e nove";
| ^ ~~~~~~~~~~~~~~
1 error generated.
Uma variável int guarda números inteiros, e a Ana tentou guardar um texto. O g++ diz "conversão inválida de const char* para int"; embaixo do texto, ele até escreve o tipo que encontrou (const char*, o jeito do C++ chamar um texto entre aspas). O Clang: "não é possível inicializar uma variável do tipo int com um valor do tipo const char[13]" (um texto de 13 bytes: as letras, os dois espaços e um marcador de fim). Nomes de tipo assustam no começo; o que importa é perceber "um lado é número, o outro é texto". Tipos são o assunto de Tipos de Dados.
Correção: o valor do tipo certo (int idade = 29;) ou uma variável do tipo certo (std::string, aula Strings). O [-fpermissive] no fim é uma opção que transformaria o erro em aviso: nunca use, o erro é real.
Missão: este programa tem quatro erros, de quatro tipos desta seção. Rode, conserte só o primeiro erro que aparecer, rode de novo, e repita. (O editor usa o Clang, então as mensagens são as da segunda forma mostrada acima.)
#include <iostream>
int main() {
std::cout << "Feira da Ana\n"
int total = 30;
cout << "Total: " << totl << "\n;
}
#include <iostream>
int main() {
std::cout << "Feira da Ana\n";
int total = 30;
std::cout << "Total: " << total << "\n";
}
5. Um erro, centenas de linhas
Às vezes um erro bobo produz uma parede de texto. A Ana esqueceu de fechar as aspas na primeira linha de uma lista:
#include <iostream>
int main() {
std::cout << "Lista de compras:\n;
std::cout << "Arroz\n";
std::cout << "Feijão\n";
std::cout << "Café\n";
}
$ g++ -std=c++23 -Wall -Wextra cascata.cpp -o cascata 2>&1 | wc -l
391 « 391 linhas de mensagem!
$ g++ -std=c++23 -Wall -Wextra cascata.cpp -o cascata 2>&1 | grep -c 'error:'
5 « mas só 5 erros; o resto são notas
$ g++ -std=c++23 -Wall -Wextra cascata.cpp -o cascata 2>&1 | head -n 8
cascata.cpp:4:18: warning: missing terminating " character
4 | std::cout << "Lista de compras:\n;
| ^
cascata.cpp:4:18: error: missing terminating " character
4 | std::cout << "Lista de compras:\n;
| ^~~~~~~~~~~~~~~~~~~~~
cascata.cpp: In function ‘int main()’:
cascata.cpp:4:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘std::ostream’ {aka ‘std::basic_ostream<char>’})
(O 2>&1 | wc -l conta as linhas da mensagem, o grep -c conta as que têm error: e o head -n 8 mostra só as 8 primeiras. São ferramentas do terminal, explicadas no Guia Bash.)
O primeiro erro é o verdadeiro: as aspas da linha 4. Sem elas, o compilador "costurou" a linha 4 com a 5 e tentou mandar um std::cout para dentro do outro (no match for ‘operator<<’). Para cada tentativa frustrada, ele lista todas as formas de << que conhece (os "candidatos"), dezenas delas, com o caminho de cada uma dentro da biblioteca. Nada disso tem a ver com o seu erro.
O Clang, nesse caso, para no essencial:
$ clang++ -std=c++23 -Wall -Wextra cascata.cpp -o cascata
cascata.cpp:4:18: warning: missing terminating '"' character [-Winvalid-pp-token]
4 | std::cout << "Lista de compras:\n;
| ^
cascata.cpp:4:18: error: expected expression
1 warning and 1 error generated.
A opção -fmax-errors=1 faz o g++ parar no primeiro erro:
$ g++ -std=c++23 -Wall -Wextra -fmax-errors=1 cascata.cpp -o cascata
cascata.cpp:4:18: warning: missing terminating " character
4 | std::cout << "Lista de compras:\n;
| ^
cascata.cpp:4:18: error: missing terminating " character
4 | std::cout << "Lista de compras:\n;
| ^~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -fmax-errors=1.
Sem essa opção, role a tela até o topo da mensagem. A regra é sempre a mesma: o primeiro erro primeiro.
6. Erros de ligação: undefined reference
Até aqui, todos os erros foram do compilador, que lê o seu código e confere as regras. Mas fazer um programa tem uma última etapa: a ligação (linking). O ligador (ld, de linker) junta o seu código já compilado com o código da biblioteca e monta o arquivo executável (o caminho todo está em Como o C++ Vira Programa). Ele tem os próprios erros, com outra cara.
Neste programa, a Ana anunciou uma função saudar (a linha 3 diz "existe uma função chamada saudar") mas esqueceu de escrevê-la. Funções são do Nível 2 (Funções); aqui basta saber que o compilador acredita no anúncio:
#include <iostream>
void saudar();
int main() {
saudar();
std::cout << "Fim\n";
}
$ g++ -std=c++23 -Wall -Wextra ligacao.cpp -o ligacao /usr/bin/x86_64-linux-gnu-ld.bfd: /tmp/ccfHe46T.o: na função "main": ligacao.cpp:(.text+0x9): referência não definida para "saudar()" collect2: error: ld returned 1 exit status
Olhe como é diferente:
- Não há
arquivo:linha:coluna. O ligador trabalha com o código já traduzido, então só sabe dizer "na funçãomain". O(.text+0x9)é uma posição dentro do código traduzido, que você pode ignorar. - A mensagem está em português! O ligador do Ubuntu tem tradução (o g++ não tem). Em inglês, que é como você vai encontrá-la em pesquisas, ela é assim:
$ LANG=C g++ -std=c++23 -Wall -Wextra ligacao.cpp -o ligacao /usr/bin/x86_64-linux-gnu-ld.bfd: /tmp/cc000u8J.o: in function `main': ligacao.cpp:(.text+0x9): undefined reference to `saudar()' collect2: error: ld returned 1 exit status
(LANG=C na frente do comando pede as mensagens sem tradução. O /tmp/cc….o é um arquivo temporário com o código compilado, que muda de nome a cada vez.)
Dá para ver as duas etapas separadas. A opção -c manda o g++ só compilar, sem ligar: o resultado é um arquivo .o ("objeto"). Repare que a compilação passa sem reclamar, e o erro só aparece na ligação:
$ g++ -std=c++23 -Wall -Wextra -c ligacao.cpp $ ls ligacao* ligacao.cpp ligacao.o « compilou! o compilador acreditou no anúncio da função $ g++ ligacao.o -o ligacao /usr/bin/x86_64-linux-gnu-ld.bfd: ligacao.o: na função "main": ligacao.cpp:(.text+0x9): referência não definida para "saudar()" collect2: error: ld returned 1 exit status
O Clang usa o mesmo ligador, então a mensagem é quase igual, com a última linha própria:
$ clang++ -std=c++23 -Wall -Wextra ligacao.cpp -o ligacao /usr/bin/x86_64-linux-gnu-ld.bfd: /tmp/ligacao-9ad276.o: na função "main": ligacao.cpp:(.text+0x5): referência não definida para "saudar()" clang++: error: linker command failed with exit code 1 (use -v to see invocation)
| Erro de compilação | Erro de ligação | |
|---|---|---|
| Quem reclama | O compilador (cc1plus no g++) | O ligador (ld, chamado pelo collect2) |
| Como começa | arquivo.cpp:linha:coluna: error: | …/ld…: …: na função "…" / in function |
| Frase típica | expected, not declared… | undefined reference to / referência não definida para; multiple definition of |
| Última linha | (nenhuma especial) | collect2: error: ld returned 1 exit status |
| Causas comuns no começo | Sintaxe, nomes, tipos | main faltando ou escrita errada (Main); função anunciada e não escrita; arquivo .cpp esquecido no comando (Compilar Vários Arquivos); biblioteca esquecida (Bibliotecas Externas) |
O erro de ligação mais comum do começo você já viu nas aulas anteriores: referência não definida para "main", quando a main não existe ou foi escrita Main (aula Sintaxe).
7. Erro, aviso e erro na hora de rodar
| Tipo | Quando aparece | O programa é criado? | Aula |
|---|---|---|---|
error: de compilação | Ao compilar | Não | Esta |
| Erro de ligação | Ao compilar, no fim | Não | Esta |
warning: | Ao compilar | Sim, mas provavelmente com um engano | Avisos |
| Erro em tempo de execução | Ao rodar: o programa quebra ou dá resultado errado | Sim | Exceções, Comportamento Indefinido, GDB |
Os erros de compilação são os melhores erros que existem: aparecem na hora, dizem a linha e não deixam um programa errado chegar a ninguém. Os piores são os que só aparecem ao rodar. É por isso que, na próxima aula, você vai pedir ao compilador que avise o máximo possível.
Referência rápida: g++ × Clang
| Situação | g++ 15 | Clang (editor do guia) |
|---|---|---|
Falta ; | expected ‘;’ before ‘…’ / expected ‘,’ or ‘;’ before ‘…’ | expected ';' after expression / at end of declaration |
Falta std:: | ‘cout’ was not declared in this scope; did you mean ‘std::cout’? | use of undeclared identifier 'cout'; did you mean 'std::cout'? |
Falta #include | ‘cout’ is not a member of ‘std’ + nota probably fixable by adding ‘#include <iostream>’ | use of undeclared identifier 'std' |
| Aspas abertas | missing terminating " character | missing terminating '"' character + expected expression |
Falta } | expected ‘}’ at end of input | expected '}' |
Sobra } | expected declaration before ‘}’ token | extraneous closing brace ('}') |
| Nome errado | ‘x’ was not declared in this scope / ‘x’ is not a member of ‘std’ | use of undeclared identifier 'x' / no member named 'x' in namespace 'std' |
| Tipo errado | invalid conversion from ‘const char*’ to ‘int’ | cannot initialize a variable of type 'int' with … |
| Ligação | undefined reference to `saudar()' + ld returned 1 exit status | o mesmo + linker command failed |
Mais mensagens, em ordem alfabética: Mensagens de Erro.
Exercícios
1. Qual linha?
Em jogo.cpp:12:7: error: expected ‘;’ before ‘return’, em que linha o g++ percebeu o erro?
2. E o erro de verdade?
Na mesma mensagem, o ; provavelmente falta no fim de qual linha?
3. Só o primeiro
Complete a opção que faz o g++ parar no primeiro erro:
4. O g++ mostrou 40 erros. O que fazer primeiro?
5. Qual destas mensagens é de um erro de ligação?
6. O compilador sugeriu did you mean ‘oct’? para um std::cot. O que isso ensina?
Missão final: o conserto completo
Missão: a Ana escreveu este boletim com pressa e o compilador recusou. Há um #include faltando, uma chave, um nome errado e um tipo errado. Use o método: primeiro erro, corrigir, compilar de novo. No fim, a compilação deve ficar sem nenhum aviso.
Boletim Nota de Matemática: 9 Nota de História: 8
int main() {
int matematica = 9;
int historia = "8";
std::cout << "Boletim\n";
std::cout << "Nota de Matemática: " << matematica << "\n";
std::cout << "Nota de História: " << historai << "\n";
#include <iostream>
int main() {
int matematica = 9;
int historia = 8;
std::cout << "Boletim\n";
std::cout << "Nota de Matemática: " << matematica << "\n";
std::cout << "Nota de História: " << historia << "\n";
}
Resumo
- Formato:
arquivo:linha:coluna: error: descrição, depois a linha copiada e o^apontando a coluna.note:complementa a mensagem anterior. - Método: o primeiro erro primeiro; vá à linha; se ela parece certa, olhe a de cima; corrija e compile de novo.
;, aspas e chaves esquecidos costumam ser percebidos depois do lugar do erro.- Um erro pode gerar centenas de linhas de notas; o que importa está no topo.
-fmax-errors=1ajuda. did you meané um palpite, quase sempre bom, às vezes não.- Erro de ligação (
undefined reference/referência não definida) vem dold, sem número de linha: algo foi anunciado mas não existe (amain, uma função). - O g++ e o Clang dizem o mesmo com palavras diferentes; o editor do guia usa o Clang.