Programadores iniciantes frustrados com a falta de um glossário de erros do compilador


66

Um amigo da minha família pediu-me um pouco de ajuda enquanto ele aprende a programar (no idioma C). Enquanto conversávamos, ele expressou frustração por ter dificuldade em entender as mensagens de erro que seu compilador (GCC) está dando a ele quando ele comete erros. Ele não entende todos os termos usados ​​e, às vezes, é a combinação deles que está além de sua compreensão. Ele estava me perguntando "Por que a documentação do compilador não inclui explicações mais longas das mensagens de erro?" - e eu não tive uma boa resposta para ele.

Eu mesmo - como programador mais experiente - estou muito raramente nessa situação, mas essas raras ocorrências acontecem - alguma mensagem de erro exótica que eu não encontrei antes. Consigo procurar a mensagem de erro em um mecanismo de pesquisa, mas aparentemente isso nem sempre funciona para ele - especialmente porque os erros que ele encontra são mais comuns e ocorrem em vários casos distintos, com os quais ele tem problemas relacionados à sua próprio.

Então, como um programador iniciante deve abordar o desafio de entender as mensagens de erro do compilador? Especificamente, com a combinação de C e GCC?


7
"Então, como um programador iniciante deve abordar o desafio de entender as mensagens de erro do compilador?" / sarcasm A primeira habilidade necessária é ser capaz de ler todos os bits da mensagem do compilador, inclusive relacioná-la com o próprio contexto. / sarcasmo desligado. Raramente acaba sendo uma falha ou bug no compilador.
πάντα ῥεῖ

10
@MasonWheeler: Um iniciante geralmente não escolhe qual compilador usar ao receber treinamento. E o GCC é um denominador comum de muitos, muitos sistemas ...
einpoklum - restabelece Monica 18/18

24
Quando se trata de erros de modelo do GCC C ++, descubro se paro de ler depois de "Erro <arquivo: linha>" e estudo o (s) arquivo (s) de origem, encontro o erro mais rapidamente, com um efeito colateral adicional de manter minha sanidade mental. se eu ler o erro real dada pelo GCC .....
mattnz

18
A solução é óbvia: use um compilador com saída menos confusa. Eu sugiro rmcc . Ele imprime Yes.ou No.depende se o seu código foi compilado ou não. Instantaneamente tira a frustração de não entender mensagens longas e sem sentido!
pipe

21
C não é uma boa linguagem para iniciantes - e você se deparou com uma das razões. Dito isto, Clang tende a oferecer erros muito melhores que também podem ser mais atraentes para iniciantes.
Theodoros Chatzigiannakis

Respostas:


164

Algumas técnicas úteis:

  • Ligue -Walle -Werror. Pode parecer contra-intuitivo quando você está lutando com a decifração de mensagens de erro para criar ainda mais mensagens de erro, mas os avisos são geralmente mais fáceis de entender e mais próximos da fonte real do problema, e ignorá-los pode levar a erros difíceis de entender .
  • Apenas tente corrigir o primeiro erro da lista. Muitas vezes, os erros se compõem, fazendo com que as mensagens de erro posteriores não sejam realmente erros reais. Corrija um e recompile. Você ficará melhor corrigindo várias mensagens de erro quando ganhar mais experiência.
  • Use a versão mais recente do compilador possível. C é uma linguagem extremamente estável. Portanto, grande parte das melhorias nos compiladores mais recentes não é adicionar recursos de idioma, mas melhorar a experiência do desenvolvedor, incluindo melhores mensagens de erro. Muitas distribuições Linux amplamente usadas têm versões muito antigas do gcc por padrão.
  • Programe incrementalmente. Não tente escrever uma tonelada de código antes de compilar. Escreva a menor quantidade possível que ainda será compilada. Se você alterou apenas uma linha desde a última compilação limpa, é muito mais fácil descobrir qual linha contém o problema real.
  • Escreva testes de unidade. Isso torna você mais confiante para fazer alterações de refatoração esclarecedor ao corrigir erros de compilação.

23
Um bom IDE também pode ajudar bastante a experiência, por exemplo. sublinhando erros em vermelho.
BlueRaja - Danny Pflughoeft

86
"Programe de forma incremental. Não tente escrever uma tonelada de código antes de compilar. Escreva a menor quantidade possível que ainda será compilada. Se você mudou apenas uma linha desde a última vez em que foi compilada de maneira limpa, é muito mais fácil descobrir qual linha contém o problema real ". Isso, muito isso. Além disso, a maioria dos IDEs irá avisá-lo se você escrever um código que não será compilado e destacar os erros.
Polygnome

4
@einpoklum: não subestime a terceira opção; As mensagens de erro do compilador melhoraram bastante. Da mesma forma, use vários compiladores (por exemplo, gcc e clang) - captura mais erros / avisos e um deles pode ter um diagnóstico melhor para um problema específico que o outro.
Mat

19
@einpoklum: escrever as coisas de forma mais incremental é muito importante , especialmente para iniciantes. Caramba, se você acredita que "pequenas tarefas de programação" não podem ser feitas gradualmente, dividindo-as em várias pequenas funções e implementando-as e compilando-as uma por uma, você deve tentar melhorar essa habilidade por si mesmo.
Doc Brown

4
Um truque que me ajudou: se a mensagem de erro mencionar a Linha N, marque a Linha N-1. Por exemplo, se estiver faltando um ponto-e-vírgula na linha 17, a mensagem de erro dirá que algo está errado com a linha 18. Isso ocorre porque o compilador estava esperando um ponto-e-vírgula, mas conseguiu outra coisa, na próxima linha.
User2023861

56

Seu amigo não precisa de um glossário. Um glossário não o ajudará. O que ele precisa é de uma melhor intuição sobre o que fazer quando ocorrerem erros do compilador.

Os erros do compilador C não são tão intuitivos quanto, digamos, erros do compilador C #, por muitas razões relacionadas principalmente à natureza "próxima ao metal" do C. A solução de erros do compilador no C não é um exercício de correspondência de padrão, porque o erro que você receber pode não ter nada a ver com o problema real. Ao contrário de C # ou Java, onde uma mensagem de erro normalmente mapeia para um local e um código precisos, é provável que os erros em C sejam numerosos e distantes.

Um exemplo disso é "ponto e vírgula esperado" ou qualquer número de erros de sintaxe que indiquem que o analisador foi desligado em algo (não necessariamente um ponto e vírgula). Ou algo como "declaração encaminhada inesperada", um erro que, quando o vejo, invariavelmente significa que houve uma maiúscula incorreta em um dos meus arquivos .h, mas que não aponta para o arquivo .h como a origem do problema.

A estratégia de seu amigo não deve ser a de combinar isso com uma lista de erros e soluções; deve entender a sintaxe e a especificação da linguagem C o suficiente para descobrir qual é o problema real .


17
Não. A idéia é conhecer o idioma suficientemente bem para saber que você não pode fazer uma atribuição a uma expressão numérica, mas apenas a uma variável. Você não precisa saber o que é um valor, e é por isso que eles não ensinam isso em cursos para iniciantes.
Robert Harvey

18
Essencialmente sim. Mas praticamente, isso não é possível. Faço isso há muito tempo e ainda recebo mensagens de erro obscuras do compilador toda vez que escrevo um programa em C. Raramente me incomodo em ler essas mensagens e tento entendê-las; em vez disso, olho para onde a mensagem de erro está apontando e, como sei como é a estrutura básica da sintaxe de um programa em C, posso identificar o problema rapidamente, sem perder tempo decifrando as mensagens de erro.
Robert Harvey

36
Em outras palavras, pedir um glossário para entender os erros do compilador é como ler o dicionário para entender o idioma inglês; não é bem assim que funciona. Você aprende e entende inglês lendo e escrevendo, não lendo o dicionário.
Robert Harvey

14
[encolher os ombros] Se você não estiver usando um dicionário para complementar apenas o seu conhecimento já existente de inglês, sugiro que você esteja fazendo errado. A última coisa que eu sugeriria é qualquer coisa que faça com que os programadores iniciantes se envolvam com o vocabulário mais do que já são. Programadores não precisam de mais palavras; eles precisam de mais habilidade.
Robert Harvey

13
@einpoklum, um glossário não vai ajudar aqui. É provável que a descrição da palavra 'valor' seja muito técnica para um iniciante ou ao longo da linha 'do que pode estar no lado esquerdo de uma tarefa', o que é igualmente inútil.
Bart van Ingen Schenau

26

Uma técnica relevante que vale a pena mencionar é o uso de um segundo compilador. A Clang investiu em melhores mensagens de erro, por exemplo, mas qualquer maneira alternativa de expressar o erro pode ser esclarecedora.

Isso é especialmente verdade para os tipos de erros mais complexos. Por exemplo, quando você cria duas construções semelhantes (incomuns para iniciantes), os compiladores geralmente têm um problema ao gerar a mensagem de erro correta. Isso pode causar confusão quando o compilador envia uma mensagem de erro sobre o uso incorreto da construção A quando você realmente pretendeu a construção B. Um segundo compilador pode inferir que você pretendeu B.


13

Alguém tentou um glossário de erros do GCC no Wikilivros há um tempo atrás, mas parece que ele nunca decolou e não foi atualizado.

A seção "Erros" é muito mais avançada que a seção "Avisos". Parece que ele foi direcionado ao G ++, mas ainda é provável que haja alguma informação útil para seu amigo lá.


12

Além das respostas acima, observe que a maioria dos compiladores não possui glossários abrangentes de erros - seria muito trabalhoso manter, pois as próprias mensagens frequentemente mudam e existem muitas delas.

O melhor substituto para um glossário é o acesso à Internet. Sempre que o compilador produzir um erro que você não entende, considere que é altamente improvável que você seja o primeiro a encontrá-lo e fique confuso. Um Google rápido da mensagem exata geralmente é suficiente para fornecer muitas informações em formato de fácil leitura, geralmente com código de exemplo muito semelhante ao seu.

Além disso, tempo e familiaridade com o idioma e o compilador são tudo o que você precisa. Isso e os bons conselhos dados por Karl Bielefeldt .


11
Eu não acho que seria muito trabalho para manter. Além disso, ele pode ser adicionado ao público, como Stackoverflow ou Wiki, com pessoas de confiança com permissões de editor.
einpoklum - reinstala Monica

6
@einpoklum Você já viu os documentos do PHP? É o que acontece quando você deixa a comunidade cuidar dessas coisas.
19418 Kevin

4
Era uma vez, manuais publicados (impressos) eram o único recurso disponível. Eles geralmente eram suficientemente escritos para fornecer as informações / orientações necessárias para resolver um problema. Com a evolução da internet, ninguém mais publica na mídia impressa (se é que está online). A qualidade do material de referência "oficial" (on-line ou não) diminuiu consideravelmente ao longo das décadas que estive programando; portanto, o melhor recurso disponível é frequentemente o Google, e os resultados mais úteis costumam aparecer no Stackoverflow.
Zenilogix 20/05/19

2
Mesmo que exista um glossário , os mecanismos de pesquisa podem ser a melhor maneira de acessá-los. Eles também são úteis para detectar quando você está em um território desconhecido: quando o único resultado da pesquisa é o código-fonte que define a mensagem de erro;)
Warbo

2
Na faculdade, certa vez recebi o erro do compilador "Dave acha que isso não deveria acontecer. Envie um email para <dave@example.com>". Enviei um email a ele e, de fato, fui o primeiro a encontrar esse erro em particular!
User1118321

6

O Padrão C usa vários termos como "lvalue" e "object" de maneiras diferentes de outras linguagens de programação, e as mensagens do compilador geralmente são escritas nesses termos. O uso da terminologia é inconsistente em algumas partes do Padrão, mas qualquer pessoa que queira aprender C deve examinar os rascunhos dos padrões C89, C99 e / ou C11, bem como os documentos lógicos para eles. Pesquisando, por exemplo, "rascunho C99" ou "justificativa C89" deve funcionar muito bem, embora você possa ter certeza de obter o documento esperado. Embora a maioria dos compiladores suporte o padrão C99, pode ser útil saber como ele difere do padrão C89, e a lógica do C89 pode oferecer alguns antecedentes históricos que versões posteriores não.


11
O padrão C é um texto muito denso e pesado. Um iniciante não tem chance de entendê-lo.
NieDzejkob

4
@NieDzejkob: A terminologia usada pelos compiladores - que parece ser a questão - é derivada do Padrão. Enquanto você estiver certo de que partes do Padrão são incompreensíveis (em parte porque ele foi elaborado pelo comitê e os autores não parecem ter uma compreensão consistente do que partes dele deveriam significar), mas qualquer pessoa que queira entender o que termos como "lvalue" significa deve estar ciente de onde eles vieram. Além disso, se alguém quiser entender por que algo como x=0x1e-xgera um erro, eu realmente não conheço outra coisa senão o padrão ... #
317

3
Concordo com @NieDzejkob: O padrão C não é o tipo de texto com o qual você deseja confrontar um novato. Iniciantes precisam de experiências práticas positivas rapidamente . E eles precisam aprender coisas novas, uma por uma, à medida que aparecem. Ler um padrão ou lógica leva muito tempo e sobrecarrega completamente um novato com informações.
Cmaster

2
@ master: Comecei com o C89 Standard há muito tempo, e não era tão ruim mesmo antes dos navegadores com um prático recurso 'localizar texto'. Concordo que os padrões posteriores se tornaram cada vez piores. Embora ninguém deva confiar no Padrão como uma única referência, é importante reconhecer a divergência entre a sabedoria popular sobre como os compiladores de microcomputadores se comportam e as maneiras pelas quais o Padrão permite que comportamentos de baixa qualidade se comportem, portanto, um estará preparado se houver. para lidar com o último.
Supercat

3
@ master: De qualquer forma, alguém que está programando C deve estar ciente do padrão e saber consultá-lo quando necessário, mesmo que não tente ler a coisa toda. Se uma pesquisa na web por uma função de biblioteca padrão, por exemplo, é possível encontrar uma referência que descreva o comportamento de uma implementação em alguns casos de canto, sem mencionar que, do ponto de vista do padrão, esses casos de canto invocam comportamento indefinido e outras implementações podem não funciona da mesma maneira. Se alguém procurar o padrão, poderá evitar esse problema.
Supercat

5

Estou surpreso que ninguém tenha dado a resposta óbvia e, suspeito, a mais usada na prática: apenas não leia as mensagens de erro.

A grande maioria do valor da maioria das mensagens de erro é simplesmente que algo está errado nessa e nessa linha. Na maioria das vezes, apenas olho para o número da linha e vou para essa linha. Minha "leitura" da mensagem de erro nesse momento geralmente é exatamente o que meu olho chama de passagem, nem mesmo um toque. Se não estiver claro imediatamente o que há de errado na linha ou perto dela, na verdade vou ler a mensagem. Esse fluxo de trabalho é ainda melhor com um IDE ou ferramenta que destaca erros no local e realiza automaticamente a sugestão de Karl Bielefeldt para considerar apenas pequenas alterações.

Obviamente, as mensagens de erro nem sempre apontam para a linha apropriada, mas também não costumam apontar para a causa raiz apropriada; portanto, mesmo um entendimento completo da mensagem de erro seria de ajuda limitada. Não demora muito para se ter uma idéia de quais mensagens de erro são mais confiáveis ​​sobre como localizar a linha correta.

Por um lado, a maioria dos erros que um iniciante provavelmente comete provavelmente será dolorosamente óbvia para um programador experiente, sem a necessidade de ajuda do compilador. Por outro lado, é muito menos provável que sejam tão óbvios para o iniciante (embora muitos sejam óbvios, a maioria dos erros são estúpidos). Neste ponto, eu concordo completamente com Robert Harvey, o novato simplesmente precisa se familiarizar com o idioma. Não há como evitar isso. Erros do compilador que fazem referência a conceitos desconhecidos ou parecem surpreendentes devem ser vistos como instruções para aprofundar o conhecimento da linguagem. Da mesma forma, nos casos em que o compilador está reclamando, mas você não consegue ver por que o código está errado.

Novamente, eu concordo com Robert Harvey que é necessária uma estratégia melhor para a utilização de erros de compilador. Eu descrevi alguns aspectos acima e a resposta de Robert Harvey fornece outros aspectos. Não está claro o que seu amigo espera fazer com esse "glossário" e é muito improvável que esse "glossário" seja realmente útil para seu amigo. As mensagens do compilador certamente não são o local para uma introdução aos conceitos da linguagem 1 e um "glossário" não é um local muito melhor para isso. Mesmo com uma descrição lúcida do significado da mensagem de erro, ele não vai lhe dizer como corrigir o problema.

1 Algumas linguagens, como Elm e Dhall (e provavelmente Racket), bem como algumas implementações de linguagens "orientadas para iniciantes", tentam fazer isso. Nesse sentido, o conselho dos MSalters de usar uma implementação diferente é diretamente relevante. Pessoalmente, acho essas coisas desinteressantes e não totalmente voltadas para o problema certo. Isso não quer dizer que não há maneiras de gerar melhores mensagens de erro, mas, para mim, elas tendem a girar em torno de tornar as crenças do compilador e a base dessas crenças mais claras.


4

Então, como um programador iniciante deve abordar o desafio de entender as mensagens de erro do compilador? Especificamente, com a combinação de C e GCC?

Diga ao seu amigo para fazer o seguinte ao encontrar um erro que ele não entende:

  • Remova / comente o código adicionado desde a última compilação bem-sucedida.
  • Coloque pequenas partes dele de volta e compile
  • Repita até o erro ocorrer

Os erros do compilador apenas informam o que o compilador não entende sobre o seu código, não o que há de errado com ele. Essa abordagem leva aproximadamente a mesma quantidade de tempo que o Google pesquisou o erro e leu alguns documentos ou uma postagem do StackOverflow, mas oferece uma compreensão muito melhor do que você está fazendo de errado.

Além disso, faça com que eles sejam compilados com frequência até que eles comecem a trabalhar em projetos que levam alguns minutos para serem construídos, detectar erros antes de adicionar muitos outros códigos ajuda muito.

Por fim, diga a eles para trabalharem em uma coisa de cada vez, não trabalhem em vários arquivos sem compilar no meio, não introduzam várias dependências de uma só vez, etc.


4

Outra técnica seria o amigo escrever seu próprio glossário ao longo do tempo, ao encontrar diferentes mensagens de erro. Muitas vezes, a melhor maneira de aprender algo é ensiná-lo. Obviamente, quando o glossário estiver pronto, ele provavelmente não precisará mais dele.

Minha experiência pessoal com o GCC é que cada mensagem de erro está relacionada a um conjunto "usual" de erros. Por exemplo, quando o GCC diz "você esqueceu o &", geralmente significa que esqueci os parênteses. Obviamente, quais erros correspondem a quais mensagens de erro dependerão do programador, outro bom motivo para o amigo escrever seu próprio glossário.


11
Este documento tem o benefício lateral extremamente importante de poder ser colocado online (mesmo que tenha apenas 5 a 10 entradas) e seria um grande diferencial ao se candidatar a estágios.
Josh Rumbut
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.