Les programmeurs novices sont frustrés par l’absence de glossaire des erreurs du compilateur

65

Un ami de ma famille m'a demandé un peu d'aide pour apprendre à 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 transmet 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'ai pas eu une bonne réponse pour lui.

En tant que programmeur plus expérimenté, je suis moi-même très rarement dans cette situation, mais ces rares occurrences se produisent - un message d'erreur exotique que je n'avais jamais rencontré auparavant. Je parviens à me débrouiller en cherchant 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 à gérer posséder.

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

einpoklum - réintègre Monica
la source
7
"Alors, comment un programmeur novice devrait-il relever le défi de comprendre les messages d'erreur du compilateur?" / sarcasme La première compétence requise est de pouvoir lire chaque bit du message du compilateur, y compris le mettre en relation avec le contexte même. / sarcasme éteint. Il s'avère rarement être un défaut ou un bogue dans le compilateur.
Posté
10
@MasonWheeler: Un novice ne choisit souvent pas le compilateur à utiliser lors d'une formation. Et GCC est un dénominateur commun à beaucoup, beaucoup de systèmes ...
einpoklum - rétablissez Monica
25
En ce qui concerne les erreurs de modèle GCC C ++, je découvre si j'arrête de lire après "Erreur <fichier: ligne>" et étudie le (s) fichier (s) source (s). Je trouve l'erreur plus rapidement, avec pour effet secondaire si je lis l'erreur réelle de GCC ...
Mattnz,
19
La solution est évidente: utilisez un compilateur avec une sortie moins déroutante. Je suggère rmcc . Il imprime Yes.ou No.selon si votre code est compilé ou non. Supprime instantanément la frustration de ne pas comprendre des messages longs et inutiles!
pipe
21
C n’est pas une bonne langue pour les débutants - et vous êtes tombé sur une des raisons. Cela étant dit, Clang a tendance à offrir de bien meilleures erreurs qui pourraient également plaire davantage aux débutants.
Theodoros Chatzigiannakis

Réponses:

163

Quelques techniques utiles:

  • Allumer -Wallet -Werror. Cela peut sembler paradoxal de créer encore plus de messages d'erreur lorsque vous avez du mal à déchiffrer les messages d' erreur, 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 conduit à des messages d'erreur ultérieurs ne constituant pas réellement des erreurs. Fixez-en un et recompilez. Vous aurez plus de facilité à corriger plusieurs messages d'erreur lorsque vous gagnerez en expérience.
  • Utilisez la dernière version du compilateur possible. C est une langue extrêmement stable. Par conséquent, une grande partie des améliorations apportées aux nouveaux compilateurs ne consiste pas à ajouter des fonctionnalités de langage, mais à améliorer l'expérience des développeurs, notamment en améliorant les messages d'erreur. Beaucoup de distributions Linux largement utilisées ont par défaut de très anciennes versions de gcc.
  • Programme progressivement. N'essayez pas d'écrire une tonne de code avant la compilation. Ecrivez le plus petit nombre possible qui sera toujours compilé. Si vous n'avez modifié qu'une ligne depuis la dernière compilation, il est beaucoup plus facile de déterminer quelle ligne contient le problème.
  • Ecrire des tests unitaires. Vous avez ainsi plus de facilité à clarifier les modifications de refactoring lors de la correction des erreurs de compilation.
Karl Bielefeldt
la source
23
Un bon IDE peut aussi grandement aider l'expérience, par exemple. soulignant les erreurs en rouge.
BlueRaja - Danny Pflughoeft
86
"Programmez progressivement. N'essayez pas d'écrire une tonne de code avant la compilation. Écrivez le plus petit nombre possible pour la compilation. Si vous n'avez modifié qu'une seule ligne depuis la dernière compilation, il est beaucoup plus facile de comprendre. quelle ligne contient le problème réel. " Ceci, tellement ça. De plus, la plupart des IDE vous avertiront si vous écrivez du code qui ne compilera pas, et soulignera les erreurs.
Polygnome
4
@einpoklum: ne sous-estimez pas la troisième option; Les messages d'erreur du compilateur se sont beaucoup améliorés. Dans le même esprit, utilisez plusieurs compilateurs (par exemple, gcc et clang). Ils capturent plus d’erreurs / avertissements et l’un d’eux aurait un meilleur diagnostic que l’autre pour un problème spécifique.
Mat
19
@einpoklum: écrire des choses de manière progressive est très courant , surtout pour les débutants. Heck, si vous pensez que les "tâches de programmation courtes" ne peuvent pas être effectuées progressivement, en les divisant en plusieurs petites fonctions, en les implémentant et en les compilant un par un, vous devriez essayer d'améliorer cette technique pour vous-même.
Doc Brown
4
Un truc qui m'a aidé: si le message d'erreur mentionne la ligne N, vérifiez la ligne N-1. Par exemple, s'il vous manque un point-virgule sur la ligne 17, le message d'erreur indiquera que quelque chose ne va pas avec la ligne 18. Cela est dû au fait que le compilateur attendait un point-virgule, mais a obtenu autre chose, à la ligne suivante.
user2023861
56

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 idée de ce qu'il faut faire lorsque des erreurs du compilateur se produisent.

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

Un exemple de ceci est "point-virgule attendu" ou un nombre quelconque d'erreurs de syntaxe indiquant que l'analyseur s'est accroché à quelque chose (pas nécessairement un point-virgule). Ou quelque chose comme "déclaration en aval inattendue", une erreur qui, lorsque je la vois, signifie invariablement que la capitalisation est erronée dans l'un de mes fichiers .h, mais qui ne désigne pas le fichier .h comme source du problème.

La stratégie de votre ami ne devrait pas consister à associer cela à une liste d’erreurs et de solutions; il devrait être de comprendre la syntaxe et la spécification du langage C assez bien pour comprendre ce que le réel problème.

Robert Harvey
la source
17
Non. L'idée est de connaître suffisamment le langage pour savoir qu'il est impossible d'affecter une expression numérique à une variable. Vous n'avez pas besoin de savoir ce qu'est une valeur, c'est pourquoi ils ne l'enseignent pas dans les cours pour débutants.
Robert Harvey
18
Essentiellement, oui. Mais pratiquement, ce n'est pas possible. Je fais cela depuis très longtemps et je reçois toujours des messages d'erreur obscurs du compilateur chaque fois que j'écris un programme C. Je prends rarement la peine de lire ces messages et d’essayer de les comprendre, cependant; Au lieu de cela, je regarde où le message d'erreur pointe et comme je sais à quoi doit ressembler la structure syntaxique de base d'un programme C, je peux repérer le problème assez rapidement sans perdre de temps à déchiffrer les messages d'erreur.
Robert Harvey
36
En d'autres termes, demander un glossaire pour comprendre les erreurs du compilateur revient un peu à lire le dictionnaire pour comprendre la langue anglaise; ça ne fonctionne pas tout à fait comme ça. Vous apprenez et comprenez l'anglais en le lisant et en l'écrivant, pas en lisant le dictionnaire.
Robert Harvey
14
[haussement d'épaules] Si vous n'utilisez pas un dictionnaire pour compléter vos connaissances en anglais, vous voudrez peut-être vous tromper. La dernière chose que je suggérerais est que tout ce qui pousse les programmeurs débutants à ne plus utiliser de vocabulaire plus qu’ils ne le sont déjà. Les programmeurs n'ont pas besoin de plus de mots; ils ont besoin de plus de compétences.
Robert Harvey
13
@einpoklum, un glossaire ne va pas aider ici. La description du mot "lvalue" sera probablement trop technique pour un débutant ou ressemblera à "ce qui peut être du côté gauche d'une tâche", ce qui est tout aussi inutile.
Bart van Ingen Schenau
26

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

Cela est particulièrement vrai pour le type d'erreur le plus complexe. 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 du mal à générer le bon message d'erreur. Cela peut être source de confusion lorsque le compilateur affiche un message d'erreur concernant l'utilisation incorrecte de la construction A alors que vous aviez l'intention de construire B. Un deuxième compilateur peut en déduire que vous aviez l'intention de B.

MSalters
la source
13

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

La section "Erreurs" est beaucoup plus avancée que la section "Avertissements". Il semble que cela visait G ++, mais il est probable que votre ami y trouvera encore des informations utiles.

nBurn
la source
12

Outre les réponses ci-dessus, notez que la plupart des compilateurs ne disposent pas de glossaires complets des erreurs. C’est beaucoup de travail à maintenir car les messages eux-mêmes changent souvent, et ils sont assez nombreux.

Le meilleur substitut à un glossaire est l'accès à Internet. Lorsque le compilateur génère une erreur que vous ne comprenez pas, rassurez-vous, il est hautement improbable que vous soyez le premier à l'avoir rencontrée et confondue. Un rapide Google du message exact suffit souvent pour vous fournir de nombreuses informations dans un format facile à lire, souvent avec un exemple de code très similaire au vôtre.

Au-delà, il ne manque que le temps et la connaissance du langage et du compilateur. Cela, et le bon conseil donné par Karl Bielefeldt .

Dúthomhas
la source
1
Je ne pense pas que ce serait beaucoup de travail à maintenir. De plus, il peut être ajouté au public, comme Stackoverflow ou un wiki, avec des autorisations de l'éditeur accordées à des personnes de confiance.
einpoklum - réintègre Monica
6
@einpoklum Avez-vous déjà vu la documentation PHP? C'est ce qui arrive quand vous laissez la communauté s'occuper de ça.
Kevin
4
Il était une fois, les manuels publiés (imprimés) étaient la seule ressource disponible. Ils étaient généralement assez bien écrits pour fournir les informations / conseils nécessaires pour résoudre un problème. Avec l'évolution d'Internet, personne ne publie plus (c'est du tout en ligne). La qualité des documents de référence "officiels" (en ligne ou non) a considérablement baissé au cours des décennies que j'ai programmées. La meilleure ressource disponible est souvent Google, et les résultats les plus utiles apparaissent souvent dans Stackoverflow.
Zenilogix
2
Même si un glossaire n'existe, les moteurs de recherche peuvent être la meilleure façon d'y accéder. Ils sont également utiles pour repérer lorsque vous vous trouvez dans un territoire inconnu: lorsque le seul résultat de recherche est le code source qui définit le message d'erreur;)
Warbo
2
Au collège, une fois, j'ai eu l'erreur de compilation "Dave ne pense pas que cela devrait arriver. Envoyez-lui un e-mail à l'adresse <[email protected]>". Je lui ai envoyé un e-mail et en fait, j'ai été le premier à avoir rencontré cette erreur!
user1118321
6

La norme C utilise un certain nombre de termes tels que "lvalue" et "objet" de manière différente 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 toute personne désirant apprendre le C devrait consulter les versions préliminaires des normes C89, C99 et / ou C11, ainsi que les documents qui les justifient. Rechercher par exemple "brouillon C99" ou "justification C89" devrait plutôt bien fonctionner, 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 logique C89 peut offrir un arrière-plan historique, contrairement aux versions ultérieures.

supercat
la source
11
La norme C est un texte très dense et lourd. Un débutant n'a aucune chance de le comprendre.
NieDzejkob
4
@NieDzejkob: La terminologie utilisée par les compilateurs - qui semble être le sujet de la question - est dérivée de la norme. Bien que vous ayez raison de dire que certaines parties de la norme sont incompréhensibles (en partie parce qu’elle a été conçue par un comité et que les auteurs ne semblent pas avoir une compréhension cohérente de ce qu’elles sont censées signifier), mais quiconque veut comprendre ce des termes tels que "lvalue" signifient devraient savoir d'où ils viennent. De plus, si l’on veut comprendre pourquoi x=0x1e-xune erreur de ce type ressemble à une erreur, je ne connais vraiment rien d’autre que la norme ...
Supercat
3
Je suis d'accord avec @NieDzejkob: le standard C n'est pas le genre de texte avec lequel vous voulez confronter un débutant. Les débutants ont besoin d'expériences pratiques positives rapidement . Et ils doivent apprendre de nouvelles choses une par une au fur et à mesure de leur apparition. La lecture d'une norme ou d'une justification prend beaucoup trop de temps tout en surchargeant complètement les débutants en informations.
cmaster
2
@cmaster: J'ai commencé avec la norme C89 il y a bien longtemps, et ce n'était pas si mal que même les jours précédant les navigateurs dotés d'une fonctionnalité pratique de recherche de texte. Je concéderai que les normes se sont détériorées de plus en plus tard. Bien que personne ne devrait s’en tenir à la norme comme référence unique, il est important de reconnaître la divergence entre la sagesse populaire sur le comportement des compilateurs de micro-ordinateurs et la manière dont la norme permet aux comportements de faible qualité de se comporter. pour faire face à ce dernier.
Supercat
3
@cmaster: Dans tous les cas, une personne qui programme C devrait connaître la norme et savoir comment la consulter en cas de besoin, même si elle n'essaiera pas de lire le texte dans son intégralité. Si vous effectuez une recherche Web pour une fonction de bibliothèque standard, par exemple, vous pouvez trouver une référence décrivant le comportement d’une implémentation dans certains cas critiques sans mentionner que, du point de vue de la norme, ces cas critiques appellent Undefined Behavior et que d’autres implémentations peuvent: fonctionne pas de la même manière. Si au lieu de cela, on recherche la norme, on peut éviter ce problème.
Supercat
5

Je suis surpris que personne n'ait donné la réponse évidente et, je suppose, la plus utilisée dans la pratique: il suffit de ne pas lire 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 le numéro de la ligne et j'y vais. Ma "lecture" du message d'erreur à ce stade correspond généralement à tout ce que mon regard attire en passant, pas même un écrémage. S'il n'est pas clair immédiatement ce qui ne va pas sur la ligne ou à proximité, je lirai le message. Ce flux de travail est encore meilleur avec un IDE ou un outillage qui met en évidence les erreurs sur-le-champ et met automatiquement en œuvre la suggestion de Karl Bielefeldt de ne prendre en compte que de petites modifications.

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

D'un côté, la plupart des erreurs qu'un novice est susceptible de commettre seront probablement douloureusement évidentes pour un programmeur expérimenté, sans l'aide du compilateur. D'un autre côté, ils sont beaucoup moins susceptibles d'être aussi évidents pour le novice (même si beaucoup le seront aussi, la plupart des erreurs sont des erreurs stupides). À ce stade, je suis tout à fait d’accord avec Robert Harvey: le novice doit simplement se familiariser davantage avec la langue. Il n'y a pas moyen 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 de la langue. De même dans les cas où le compilateur se plaint mais que vous ne voyez pas pourquoi le code est erroné.

Encore une fois, je suis d'accord avec Robert Harvey pour dire qu'une meilleure stratégie d'utilisation des erreurs de compilation est nécessaire. J'ai souligné certains aspects ci-dessus et la réponse de Robert Harvey en donne d'autres. On ne sait même pas 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 idéal pour une introduction aux concepts du langage 1 et un "glossaire" n’est pas vraiment un meilleur endroit pour cela. Même avec une description claire du message d'erreur, cela ne vous indiquera pas comment résoudre le problème.

1 Quelques langues, 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, le conseil de MSalters d'utiliser une implémentation différente est directement pertinent. Personnellement, je trouve que de telles choses ne sont pas convaincantes et ne visent pas vraiment le bon problème. Cela ne veut pas dire qu'il n'y a pas moyen de créer de meilleurs messages d'erreur, mais pour moi, ils ont tendance à tourner autour de la clarification des croyances du compilateur et de la base de celles-ci.

Derek Elkins
la source
4

Alors, comment un programmeur novice devrait-il relever 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 quand ils rencontrent une erreur qu'ils ne comprennent pas:

  • Supprimez / commentez le code ajouté depuis la dernière construction réussie.
  • Remettez 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 Google pour lire l’erreur et lire certains documents ou un article StackOverflow, mais donne une bien meilleure compréhension de ce que vous faites de travers.

Assurez-vous également qu'ils compilent souvent jusqu'à ce qu'ils commencent à travailler sur des projets dont la construction prend quelques minutes, en repérant les erreurs avant d'ajouter trop de code aide beaucoup.

Enfin, dites-leur de ne travailler que sur une tâche à la fois, de ne pas travailler dans plusieurs fichiers sans les compiler, de ne pas introduire plusieurs dépendances à la fois, etc.

Kevin
la source
4

Une autre technique consisterait pour l’ami à écrire son propre glossaire au fil du temps s’il rencontre différents messages d’erreur. Souvent, le meilleur moyen d'apprendre quelque chose est de l'enseigner. Bien sûr, à la fin du glossaire, 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, quand GCC dit "as-tu oublié le &", cela signifie généralement que j'ai oublié les parenthèses. Bien sûr, quelles erreurs correspondent aux messages d'erreur qui dépendent du programmeur, une autre bonne raison pour l'ami d'écrire son propre glossaire.

Owen
la source
1
Ce document présente l’avantage supplémentaire extrêmement important qu’il pourrait être mis en ligne (même s’il ne compte que 5 à 10 entrées) et constituerait un atout majeur pour une candidature à un stage.
Josh Rumbut