Programador (es) novato (s) frustrado pela falta de um glossário de erros do compilador

65

Um amigo da minha família me pediu ajuda enquanto aprende a programar (na linguagem C). Enquanto conversávamos, ele expressou sua frustração por ter dificuldade em entender as mensagens de erro que seu compilador (GCC) está dando a ele quando 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 "Como a documentação do compilador não inclui explicações mais longas das mensagens de erro?" - e eu não tenho uma boa resposta para ele.

Eu mesmo - como programador mais experiente - estou muito raramente nessa situação, mas essas ocorrências raras acontecem - uma mensagem de erro exótica que eu não havia encontrado antes. Consigo sobreviver procurando a mensagem de erro em um mecanismo de busca, 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, o que ele tem dificuldade em relacionar-se com a sua mensagem. próprio.

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

    
por einpoklum 18.05.2018 / 20:18
fonte

9 respostas

164

Algumas técnicas úteis:

  • Ativar -Wall e -Werror . Pode parecer contra-intuitivo quando você está lutando com decifrar mensagens de erro para criar até mesmo mais mensagens de erro, mas os avisos normalmente são mais fáceis de entender e mais próximos da fonte real do problema, e ignorá-los pode levar para erros que são difíceis de entender.
  • Tente corrigir o primeiro erro na lista. Frequentemente, os erros são compostos uns nos outros, levando a mensagens de erro posteriores a não se tornarem erros reais. Corrigir um e recompilar. Você ficará melhor ao corrigir 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, uma 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 utilizadas têm muito versões antigas do gcc por padrão.
  • Programe incrementalmente. Não tente escrever uma tonelada de código antes de compilar. Escreva o menor valor possível que ainda será compilado. Se você alterou apenas uma linha desde a última vez que compilou corretamente, é muito mais fácil descobrir qual linha contém o problema real.
  • Escreva testes unitários. Isso deixa você mais confiante para esclarecer as alterações de refatoração ao corrigir erros de compilação.
por 18.05.2018 / 22:09
fonte
56

Seu amigo não precisa de um glossário. Um glossário não irá ajudá-lo. O que ele precisa é de uma melhor intuição sobre o que fazer quando ocorrerem erros no compilador.

Os erros do compilador C não são tão intuitivos quanto, digamos, erros do compilador C #, por muitos motivos, principalmente relacionados à natureza "próxima do metal" do C. Resolver erros do compilador em C não é um exercício de correspondência de padrões, o erro que você recebe pode não ter nada a ver com o problema real. Ao contrário do C # ou do Java, em que uma mensagem de erro geralmente é mapeada para um local de código e um problema precisos, os erros em C provavelmente são numerosos e distantes.

Um exemplo disso é "ponto-e-vírgula esperado" ou qualquer número de erros de sintaxe que indiquem que o analisador ficou preso em algo (não necessariamente um ponto-e-vírgula). Ou algo como "declaração antecipada inesperada", um erro que, quando eu vejo isso, invariavelmente significa que fiquei com letras maiúsculas incorretas em um dos meus arquivos .h, mas que não aponta para o arquivo .h como a origem do problema.

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

    
por 18.05.2018 / 20:28
fonte
26

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

Isso é especialmente verdade para o tipo mais complexo de erros. Por exemplo, quando você mistura duas construções similares (não incomuns para iniciantes), os compiladores normalmente têm um problema ao gerar a mensagem de erro correta. Isso pode causar confusão quando o compilador fornece 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ê pretendia B.

    
por 19.05.2018 / 00:42
fonte
12

Alguém fez uma tentativa em um glossário de erro do GCC no Wikilivros há algum tempo, mas parece que nunca decolou e não foi atualizado.

A seção "Erros" é muito mais avançada do que a seção "Avisos". Parece que foi destinado a G + +, mas ainda é provável que haja alguma informação de uso para seu amigo lá.

    
por 19.05.2018 / 02:35
fonte
12

Além das respostas acima, note que a maioria dos compiladores não tem glossários de erro abrangentes - isso seria muito trabalho para manter, já que as mensagens em si mudam com frequência, e há bastante muitos deles.

O melhor substituto para um glossário é o acesso à internet. Sempre que o compilador produz um erro que você não entende, considere que é altamente improvável que você seja o primeiro a encontrá-lo e a ser confundido. 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, o tempo e a familiaridade com a linguagem e o compilador são tudo o que você precisa. Isso e o bom conselho dado por Karl Bielefeldt .

    
por 19.05.2018 / 03:03
fonte
6

O C Standard usa um número de termos como "lvalue" e "object" de maneiras diferentes de outras linguagens de programação, e as mensagens do compilador são freqüentemente escritas em tais 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 de lógica para eles. Pesquisando por, e. "C99 draft" ou "C89 rationale" devem funcionar muito bem, embora você precise se certificar de obter o documento que está esperando. Embora a maioria dos compiladores suporte o C99 Standard, pode ser útil saber como ele difere do C89 Standard, e o raciocínio C89 pode oferecer algum contexto histórico que versões posteriores não fazem.

    
por 19.05.2018 / 01:00
fonte
5

Estou surpreso que ninguém deu 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 em tal e tal linha. Na maior parte do tempo, apenas olho para o número da linha e vou para essa linha. Minha "leitura" da mensagem de erro nesse ponto geralmente é apenas o que meus olhos captam de passagem, nem mesmo um desdém. Se não estiver imediatamente claro o que está errado na linha ou perto dela, então eu realmente leio a mensagem. Esse fluxo de trabalho é ainda melhor com um IDE ou ferramenta que destaca os erros no momento e automaticamente realiza a sugestão de Karl Bielefeldt de considerar apenas pequenas alterações.

É claro que as mensagens de erro nem sempre apontam para a linha apropriada, mas muitas vezes também não apontam para a causa raiz apropriada, portanto, mesmo um entendimento completo da mensagem de erro seria de ajuda limitada. Não demorou muito para ter uma ideia de quais mensagens de erro são mais confiáveis sobre a localização da linha correta.

Por um lado, a maioria dos erros que um iniciante provavelmente fará provavelmente serão dolorosamente óbvios para um programador experiente, sem a necessidade de ajuda do compilador. Por outro lado, eles são muito menos propensos a serem tão óbvios para o novato (embora muitos sejam óbvios, a maioria dos erros são erros estúpidos). Neste ponto, eu concordo completamente com Robert Harvey, o novato simplesmente precisa se familiarizar mais com a linguagem. Não há como evitar isso. Erros de compiladores que referenciam conceitos desconhecidos ou parecem surpreendentes devem ser vistos como sugestões para aprofundar o conhecimento da linguagem. Da mesma forma, para 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 uma estratégia melhor para utilizar erros do compilador é necessária. Eu descrevi alguns aspectos acima e a resposta de Robert Harvey dá outros aspectos. Não é nem mesmo 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 lugar para uma introdução aos conceitos da linguagem 1 e um "glossário" não é um lugar muito melhor para isso. Mesmo com uma descrição lúcida do que a mensagem de erro significa, ela não lhe dirá como consertar o problema.

1 Alguns idiomas, como o Elm e o Dhall (e provavelmente o Racket), bem como algumas implementações de linguagens "orientadas ao iniciante" tentam fazer isso. Nesse sentido, o conselho de MSalter para usar uma implementação diferente é diretamente relevante. Pessoalmente, acho que essas coisas não são convincentes e não visam o problema certo. Isso não quer dizer que não há maneiras de se fazer 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.

    
por 20.05.2018 / 12:08
fonte
4

So, how should a novice programmer approach the challenge of understanding compiler error messages? Specifically, with the combination of C and GCC?

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

  • Remover / comentar o código adicionado desde a última compilação bem-sucedida.
  • Coloque pequenas partes de volta e compile
  • Repetir 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 está errado com ele. Essa abordagem leva aproximadamente a mesma quantidade de tempo que pesquisando o erro no Google e lendo alguns documentos ou uma postagem do StackOverflow, mas fornece uma compreensão muito melhor do que você está fazendo de errado.

Também os compile freqüentemente até que eles comecem a trabalhar em projetos que demoram alguns minutos para serem compilados, identificar erros antes de adicionar muito outro código ajuda bastante.

Por último, diga-lhes para trabalhar em uma coisa de cada vez, não trabalhe em vários arquivos sem compilar, não introduza várias dependências de uma só vez, etc.

    
por 19.05.2018 / 14:35
fonte
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 alguma coisa é ensiná-la. É claro, 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 "comum" de erros. Por exemplo, quando o GCC disser "esqueceu o &" isso geralmente significa que eu esqueci parênteses. É claro, quais erros correspondem a quais mensagens de erro dependerão do programador, outra boa razão para o amigo escrever seu próprio glossário.

    
por 20.05.2018 / 15:10
fonte