web-dev-qa-db-fra.com

Programmeur (s) novice (s) frustré par le manque d'un glossaire des erreurs de compilation

Un ami de ma famille m'a demandé un peu d'aide pendant qu'il apprend à programmer (en langage C). Pendant que nous parlions, il a exprimé sa frustration d'avoir du mal à comprendre les messages d'erreur que son compilateur (GCC) lui donne lorsqu'il fait des erreurs. Il ne comprend pas tous les termes utilisés, et parfois c'est leur combinaison qui dépasse sa compréhension. Il me demandait "Comment se fait-il que la documentation du compilateur n'inclue pas d'explications plus longues sur les messages d'erreur?" - et je n'avais pas de bonne réponse pour lui.

Moi-même - en tant que programmeur plus expérimenté - je suis très rarement dans cette situation, mais ces rares événements se produisent - un message d'erreur exotique que je n'avais pas rencontré auparavant. Je parviens à me débrouiller en recherchant le message d'erreur dans un moteur de recherche, mais apparemment cela ne fonctionne pas toujours pour lui - d'autant plus que les erreurs qu'il rencontre sont plus courantes et se produisent dans plusieurs cas distincts, qu'il a du mal à relier à son posséder.

Alors, comment un programmeur novice devrait-il aborder le défi de comprendre les messages d'erreur du compilateur? Plus précisément, avec la combinaison de C et GCC?

65
einpoklum

Quelques techniques utiles:

  • Allumer -Wall et -Werror. Cela peut sembler contre-intuitif lorsque vous avez du mal à déchiffrer les messages d'erreur pour créer même des messages d'erreur plus, mais les avertissements sont généralement plus faciles à comprendre et plus proches de la source réelle du problème, et les ignorer peut conduire à des erreurs difficiles à comprendre.
  • Essayez simplement de corriger la première erreur de la liste. Souvent, les erreurs se combinent, ce qui fait que les messages d'erreur ultérieurs ne sont pas vraiment des erreurs réelles. Fixez-en un et recompilez. Vous améliorerez la correction de plusieurs messages d'erreur lorsque vous gagnerez en expérience.
  • Utilisez la dernière version du compilateur possible. C est un langage extrêmement stable. Par conséquent, une grande partie des améliorations des nouveaux compilateurs ne consiste pas à ajouter des fonctionnalités linguistiques, mais à améliorer l'expérience des développeurs, y compris de meilleurs messages d'erreur. De nombreuses distributions Linux largement utilisées ont des versions très très anciennes de gcc par défaut.
  • Programmez progressivement. N'essayez pas d'écrire une tonne de code avant de compiler. Écrivez le montant le plus court possible qui sera toujours compilé. Si vous n'avez modifié qu'une seule ligne depuis la dernière fois qu'elle a été compilée proprement, il est beaucoup plus facile de déterminer quelle ligne contient le problème réel.
  • Écrire des tests unitaires. Cela vous rend plus confiant pour clarifier les modifications de refactorisation lors de la correction des erreurs de compilation.
163
Karl Bielefeldt

Votre ami n'a pas besoin d'un glossaire. Un glossaire ne l'aidera pas. Ce dont il a besoin, c'est d'une meilleure intuition sur ce qu'il faut faire lorsque des erreurs de compilation se produisent.

Les erreurs du compilateur C ne sont pas aussi intuitives que, par exemple, les erreurs du compilateur C #, pour de nombreuses raisons principalement liées à la nature "proche du métal" de C. Résoudre les erreurs du compilateur en C n'est pas un exercice de correspondance de modèle, car l'erreur que vous recevoir n'a peut-être rien à voir avec le problème réel. Contrairement à C # ou Java, où un message d'erreur correspond généralement à un emplacement de code précis et à un problème, les erreurs en C sont susceptibles d'être nombreuses et éloignées.

Un exemple de ceci est "point-virgule attendu" ou un certain nombre d'erreurs de syntaxe qui indiquent que l'analyseur s'est accroché à quelque chose (pas nécessairement un point-virgule). Ou quelque chose comme "déclaration anticipée inattendue", une erreur qui, quand je le vois, signifie invariablement que j'ai mal saisi la capitalisation dans l'un de mes fichiers .h, mais qui ne pointe pas vers le fichier .h comme source du problème.

La stratégie de votre ami ne devrait pas être de faire correspondre ce modèle à une liste d'erreurs et de solutions; cela devrait être de comprendre suffisamment la syntaxe et la spécification du langage C pour comprendre quel est le problème réel .

56
Robert Harvey

Une technique pertinente qui mérite d'être mentionnée est d'utiliser un deuxième compilateur. Clang a investi dans de meilleurs messages d'erreur, par exemple, mais toute autre façon de formuler l'erreur peut être éclairante.

Cela est particulièrement vrai pour les types d'erreurs les plus complexes. Par exemple, lorsque vous mélangez deux constructions similaires (ce qui n'est pas inhabituel pour les débutants), les compilateurs ont généralement un problème pour générer le bon message d'erreur. Cela peut provoquer de la confusion lorsque le compilateur donne un message d'erreur sur l'utilisation incorrecte de la construction A alors que vous vouliez réellement la construction B. Un deuxième compilateur pourrait déduire que vous vouliez B.

26
MSalters

Quelqu'un a tenté n glossaire d'erreur GCC sur Wikibooks il y a quelque temps, mais il semble qu'il n'ait jamais vraiment décollé et n'a pas été mis à jour.

La section "Erreurs" est beaucoup plus avancée que la section "Avertissements". On dirait qu'il était destiné à G ++, mais il y aura probablement encore des informations utiles à votre ami.

13
nBurn

En plus des réponses ci-dessus, notez que la plupart des compilateurs n'ont pas de glossaires d'erreur complets - ce serait beaucoup de travail à maintenir comme messages eux-mêmes changent souvent, et ils sont nombreux.

Le meilleur substitut d'un glossaire est l'accès à Internet. Chaque fois que le compilateur produit une erreur que vous ne comprenez pas, rassurez-vous, il est très peu probable que vous soyez le premier à l'avoir rencontrée et à être confus. Un rapide Google du message exact est souvent suffisant pour vous donner beaucoup d'informations dans un format facile à lire, souvent avec un exemple de code très similaire au vôtre.

Au-delà de cela, vous n'avez besoin que de temps et de familiarité avec le langage et le compilateur. Cela, et les bons conseils donnés par Karl Bielefeldt .

12
Dúthomhas

La norme C utilise un certain nombre de termes tels que "lvalue" et "objet" de manières différentes des autres langages de programmation, et les messages du compilateur sont souvent écrits en ces termes. L'utilisation de la terminologie est incohérente dans certaines parties de la norme, mais quiconque souhaite apprendre le C devrait consulter les projets de normes C89, C99 et/ou C11 ainsi que les documents de justification à leur sujet. Recherche par exemple Le "projet C99" ou la "justification C89" devrait fonctionner assez bien, mais vous devrez peut-être vous assurer d'obtenir le document que vous attendez. Bien que la plupart des compilateurs prennent en charge la norme C99, il peut être utile de savoir en quoi elle diffère de la norme C89, et la justification de C89 peut offrir un contexte historique contrairement aux versions ultérieures.

6
supercat

Je suis surpris que personne n'ait donné la réponse évidente et, je suppose, celle la plus souvent utilisée dans la pratique: ne lisez pas les messages d'erreur.

La grande majorité de la valeur de la plupart des messages d'erreur est simplement que quelque chose ne va pas sur telle ou telle ligne. La plupart du temps, je regarde simplement le numéro de ligne et je vais sur cette ligne. Ma "lecture" du message d'erreur à ce moment-là est généralement juste ce que mon œil capte en passant, pas même un écrémé. S'il n'est pas immédiatement clair ce qui ne va pas sur ou près de la ligne, alors je vais lire le message. Ce flux de travail est encore meilleur avec un IDE ou un outil qui met en évidence les erreurs sur place et accomplit automatiquement la suggestion de Karl Bielefeldt de ne considérer que les petits changements.

Bien sûr, les messages d'erreur ne pointent pas toujours vers la ligne appropriée, mais ils ne pointent souvent pas non plus vers la cause racine appropriée, donc même une compréhension complète du message d'erreur serait d'une aide limitée. Il ne faut pas longtemps pour se faire une idée des messages d'erreur les plus fiables pour localiser la ligne appropriée.

D'une part, la plupart des erreurs qu'un novice est susceptible de faire sont susceptibles d'être douloureusement évidentes pour un programmeur expérimenté sans l'aide du compilateur étant nécessaire. D'un autre côté, ils sont beaucoup moins susceptibles d'être si évidents pour le novice (bien que beaucoup soient évidents, la plupart des erreurs sont des erreurs stupides). À ce stade, je suis entièrement d'accord avec Robert Harvey, le novice doit simplement se familiariser avec la langue. Il est impossible d'éviter cela. Les erreurs de compilation qui font référence à des concepts inconnus ou qui semblent surprenantes devraient être considérées comme des incitations à approfondir la connaissance du langage. De même pour les cas où le compilateur se plaint mais vous ne voyez pas pourquoi le code est incorrect.

Encore une fois, je suis d'accord avec Robert Harvey qu'une meilleure stratégie d'utilisation des erreurs du compilateur est nécessaire. J'ai décrit certains aspects ci-dessus et la réponse de Robert Harvey en donne d'autres. On ne sait même pas exactement ce que votre ami espère faire avec un tel "glossaire", et il est très peu probable qu'un tel "glossaire" soit réellement d'une grande utilité pour votre ami. Les messages du compilateur ne sont certainement pas le lieu d'une introduction aux concepts du langage1 et un "glossaire" n'est pas vraiment un meilleur endroit pour cela. Même avec une description claire de la signification du message d'erreur, cela ne vous dira pas comment corriger le problème.

1 Cependant, quelques langages, comme Elm et Dhall (et probablement Racket), ainsi que quelques implémentations de langues "orientées débutant" tentent de le faire. Dans cet esprit, les conseils de MSalters pour utiliser une implémentation différente sont directement pertinents. Personnellement, je trouve ces choses peu convaincantes et pas tout à fait destinées au bon problème. Cela ne veut pas dire qu'il n'y a pas de moyen de faire de meilleurs messages d'erreur, mais, pour moi, ils ont tendance à clarifier les croyances du compilateur et la base de ces croyances.

5

Une autre technique serait que l'ami rédige son propre glossaire au fil du temps alors qu'il rencontre différents messages d'erreur. Souvent, la meilleure façon d'apprendre quelque chose est de l'enseigner. Bien sûr, au moment où le glossaire sera terminé, il n'en aura probablement plus besoin.

Mon expérience personnelle avec GCC est que chaque message d'erreur se rapporte à un ensemble "habituel" d'erreurs. Par exemple, lorsque GCC dit "avez-vous oublié le &", cela signifie généralement que j'ai oublié les parenthèses. Bien sûr, quelles erreurs correspondent à quels messages d'erreur dépendront du programmeur, une autre bonne raison pour l'ami d'écrire son propre glossaire.

4
Owen

Alors, comment un programmeur novice devrait-il aborder le défi de comprendre les messages d'erreur du compilateur? Plus précisément, avec la combinaison de C et GCC?

Dites à votre ami de faire ce qui suit lorsqu'il rencontre une erreur qu'il ne comprend pas:

  • Supprimez/commentez le code ajouté depuis la dernière génération réussie.
  • Remettez-en de petites parties et compilez
  • Répétez jusqu'à ce que l'erreur se produise

Les erreurs du compilateur vous indiquent uniquement ce que le compilateur ne comprend pas à propos de votre code, et non ce qui ne va pas. Cette approche prend à peu près le même temps que la recherche de l'erreur sur Google et la lecture de certains documents ou d'un article StackOverflow, mais donne une bien meilleure compréhension de ce que vous faites de mal.

Faites-les également compiler souvent jusqu'à ce qu'ils commencent à travailler sur des projets qui prennent quelques minutes à construire, repérer les erreurs avant d'ajouter trop de code aide beaucoup.

Enfin, dites-leur de travailler sur une seule chose à la fois, de ne pas travailler dans plusieurs fichiers sans compiler entre eux, de ne pas introduire plusieurs dépendances à la fois, etc.

4
Kevin