コンパイラエラーの用語集がないために不満な初心者プログラマ


66

私の家族の友人が、プログラミング(C言語)を学ぶときに少し助けを求めました。私たちが話していたとき、彼はコンパイラー(GCC)がエラーを起こしたときに彼に与えるエラーメッセージを理解するのに苦労していることにフラストレーションを表明しました。彼は、使用されているすべての用語を理解していません。また、それらの組み合わせが理解できない場合もあります。「コンパイラのドキュメントに、エラーメッセージの詳細な説明が含まれていないのはなぜですか?」-そして、私は彼に良い答えがありませんでした。

私自身-より経験豊富なプログラマーとして-この状況ではめったにありませんが、これらのまれな出来事は起こります-私が以前に遭遇したことのないいくつかのエキゾチックなエラーメッセージ。私は検索エンジンでエラーメッセージを探すことで何とかやっていくことができますが、どうやらそれは彼のために常に機能するとは限りません-特に彼が遭遇するエラーはより一般的であり、彼が彼に関連するトラブルを抱えている複数の異なるケースで発生するため自分の。

それでは、初心者プログラマはコンパイラエラーメッセージを理解するという課題にどのように取り組むべきでしょうか?具体的には、CとGCCの組み合わせで?


7
「では、初心者のプログラマは、コンパイラエラーメッセージを理解するという課題にどのように取り組むべきでしょうか?」 / sarcasm必要な最初のスキルは、コンパイラメッセージからすべてのビットを読み取れるようにすることです。これには、コンテキストとの関連付けも含まれます。/ sarcasm off。それはめったにコンパイラのバグやバグではないことが判明しました。
ῥεῖπάντα

10
@MasonWheeler:初心者は、トレーニングを受けるときに使用するコンパイラを選択しないことがよくあります。そして、GCCは多くの、多くのシステムの共通分母です...
アインポクラム-モニカを

24
GCC C ++テンプレートエラーに関しては、「Error <file:line>」の後に読み取りを停止し、ソースファイルを調べると、エラーをすばやく見つけ、正気を維持するという副作用がありますGCCによって与えられた実際のエラーを読んだ場合
.....-mattnz

18
解決策は明らかです。わかりやすい出力のコンパイラを使用してください。rmccをお勧めします。コードをコンパイルするかどうYes.かにNo.応じて出力します。長くて意味のないメッセージを理解していないことからフラストレーションを即座に取り除きます!
パイプ

21
Cは初心者には適した言語ではありません。その理由の1つにつまずいたことがあります。そうは言っても、Clangはより良いエラーを提供する傾向があり、初心者にとっても魅力的です。
14:43にセオドロスチャツィジアンナキス

回答:


164

いくつかの便利なテクニック:

  • とをオンに-Wall-Werrorます。エラーメッセージを解読してさらに多くのエラーメッセージを作成しようとすると直観に反するように思えるかもしれませんが、通常、警告は理解しやすく、問題の実際の原因により近いため、無視するとエラーを理解しにくくなる可能性があります。
  • リストの最初のエラーを修正してください。多くの場合、エラーは互いに重なり合い、実際のエラーではない後のエラーメッセージにつながります。修正して再コンパイルしてください。経験を積むと、複数のエラーメッセージの修正が上手くなります。
  • 可能な限り最新のコンパイラバージョンを使用してください。Cは非常に安定した言語です。したがって、新しいコンパイラの改善の大部分は、言語機能を追加することではなく、より良いエラーメッセージを含む開発者のエクスペリエンスを改善することです。広く使用されている多くのLinuxディストリビューションには、デフォルトでgccの非常に古いバージョンがあります。
  • 増分プログラム。コンパイルする前に大量のコードを書こうとしないでください。コンパイルする可能性のある最短の量を書きます。前回正常にコンパイルしてから1行しか変更していない場合、どの行に実際の問題が含まれているかを把握する方がはるかに簡単です。
  • 単体テストを作成します。コンパイルエラーを修正する際に、リファクタリングの変更を明確にする自信がつきます。

23
優れたIDEは、たとえば、エラーに赤の下線を引きます。
BlueRaja-ダニーPflughoeft

86
「プログラムをインクリメンタルに。コンパイルする前に大量のコードを書こうとしないでください。それでもコンパイルできる限り短い量を書いてください。最後にきれいにコンパイルしてから1行だけを変更した場合、どの行に実際の問題が含まれていますか。」これ、これだけ。また、ほとんどのIDEは、コンパイルできないコードを記述して警告を表示し、エラーを強調表示します。
ポリグノーム

4
@einpoklum:3番目のオプションを過小評価しないでください。コンパイラのエラーメッセージが大幅に改善されました。同様に、いくつかのコンパイラー(gccやclangなど)を使用します-より多くのエラー/警告をキャッチし、特定の問題に対して他のコンパイラーよりも優れた診断を行うことができます。
マット

19
@einpoklum:物事を少しずつ書くことは、特に初心者にとって非常に重要です。あなたは「短いプログラミングの割り当ては、」いくつかの小さな機能にそれらを分割することによって、インクリメンタルに行われ、1つずつを実装し、コンパイルすることができないと考えている場合ヘック、あなた自身のためにそのスキルを向上させるために試してみてください...
ドク・ブラウン

4
私を助けたトリック:エラーメッセージに行Nが記載されている場合は、行N-1を確認してください。たとえば、17行目でセミコロンが欠落している場合、エラーメッセージは18行目で何か間違っていることを示します。これは、コンパイラがセミコロンを予期していましたが、代わりに次の行で何かを得たためです。
user2023861

56

あなたの友人は用語集を必要としません。 用語集は彼を助けません。彼が必要とするのは、コンパイラエラーが発生したときに何をすべきかについての直感です。

Cコンパイラエラーは、たとえばC#コンパイラエラーほど直感的ではありません。多くの理由は、主にCの「金属に近い」性質に関係しているためです。Cでのコンパイラエラーの解決は、パターンマッチングの練習ではありません。 receiveは、実際の問題とは何の関係もありません。通常、エラーメッセージが正確なコードの場所と問題にマップされるC#やJavaとは異なり、Cのエラーは多数あり、遠く離れている可能性があります。

この例としては、「セミコロンが必要」または構文解析器が何か(必ずしもセミコロンではない)にハングアップしたことを示す任意の数の構文エラーがあります。または、「予期しない前方宣言」などのエラーは、見たときに、.hファイルの1つで大文字が間違っていることを常に意味しますが、問題の原因として.hファイルを指していません。

友人の戦略は、これをエラーと解決策のリストにパターン一致させることではありません。C言語の構文と仕様を十分に理解して、実際の問題を把握する必要があります。


17
いいえ。アイデアは、数式に代入することはできず、変数にのみ代入できることを十分に理解することです。左辺値が何であるかを知る必要はまったくありません。そのため、初心者コースではそれを教えません。
ロバートハーヴェイ

18
基本的にははい。しかし実際には、それは不可能です。私はこれを非常に長い間行ってきましたが、Cプログラムを書くたびにあいまいなコンパイラエラーメッセージが表示されます。ただし、これらのメッセージを読んで理解しようとすることはほとんどありません。代わりに、エラーメッセージが指す場所を調べます。Cプログラムの基本的な構文構造がどのように見えるかを知っているので、エラーメッセージを解読するのに時間を費やすことなく、問題を比較的すばやく見つけることができます。
ロバートハーヴェイ

36
別の言い方をすれば、コンパイラーのエラーを理解するための用語集を要求することは、英語を理解するために辞書を読むことに少し似ています。それはまったく機能しません。辞書を読むのではなく、読み書きして英語を学び理解します。
ロバートハーヴェイ

14
[shrug] 辞書を使用して、既に存在する英語の知識を補うだけではない場合、間違っていることをお勧めします。私がお勧めする最後のことは、初心者プログラマーが既にある以上に語彙に夢中になる原因になります。プログラマーはこれ以上言葉を必要としません。もっとスキル
ロバートハーヴェイ

13
@einpoklum、用語集はここでは役に立ちません。「左辺値」という言葉の説明は、初心者にとって技術的すぎるか、「割り当ての左側にある可能性がある」という行に沿っている可能性が高く、同じように役に立ちません。
バートヴァンインゲンシェナウ

26

言及する価値のある関連技術は、2番目のコンパイラを使用することです。たとえば、Clangはより優れたエラーメッセージに投資していますが、エラーを表現する別の方法は啓発的です。

これは、最も複雑なタイプのエラーの場合に特にそうです。たとえば、2つの類似した構造(初心者にとっては珍しいことではありません)を混在させると、通常、コンパイラは正しいエラーメッセージを生成する際に問題を抱えます。これは、実際にコンストラクトBを意図したときに、コンパイラーがコンストラクトAの誤った使用法に関するエラーメッセージを出すと混乱を引き起こす可能性があります。


13

誰かがウィキブックスのGCCエラー用語集を少し前に試みましが、それはまったく成功せず、更新されていないようです。

「エラー」セクションは、「警告」セクションよりもはるかに詳細です。G ++を対象としたように見えますが、そこにはあなたの友人に役立つ情報がまだ残っている可能性があります。


12

上記の回答に加えて、ほとんどのコンパイラに包括的なエラー用語集がないことに注意してください。これらはメッセージ自体が頻繁に変更されるため、維持するのに多大な労力が必要であり、非常に多くあります。

用語集の最良の代替は、インターネットへのアクセスです。コンパイラーが理解できないエラーを生成するときはいつでも、最初に遭遇して混乱した可能性が非常に低いと安心してください。正確なメッセージをすばやくGoogleに入力するだけで、多くの情報を読みやすい形式で提供することができます。多くの場合、サンプルコードと非常によく似ています。

それ以外に、言語とコンパイラーについての時間と知識があれば十分です。それと、Karl Bielefeldtからの良いアドバイス


1
維持するのに多くの労力がかかるとは思いません。さらに、StackoverflowやWikiなどの一般の人々が、編集者の許可を与えられた信頼できる人に追加することができます。
アインポクルム-モニカを

6
@einpoklum PHPドキュメントを見たことがありますか?コミュニティにそのようなことを任せると、それが起こります。
ケビン

4
むかしむかし、公開された(印刷された)マニュアルのみが利用可能なリソースでした。それらは通常、問題を解決するために必要な情報/ガイダンスを提供するために十分に書かれていました。インターネットの進化に伴い、もはや印刷物で出版する人はいません(オンラインの場合)。「公式」参照資料(オンラインまたはその他)の品質は、私がプログラミングしてきた数十年間でかなり低下しているため、利用可能な最良のリソースは多くの場合Googleであり、Stackoverflowで最も有用な結果が得られることがよくあります。
Zenilogix

2
用語集存在する場合でも、検索エンジンがそれらにアクセスするための最良の方法かもしれません。また、未知の領域にいるときの発見にも役立ちます。検索結果がエラーメッセージを定義するソースコードのみである場合;)
Warbo

2
大学で、「デイブはこれが起こるとは思わない。<dave@example.com>で彼にメールを送ってください」というコンパイラエラーを受け取りました。私は彼にメールを送りましたが、実際、私はその特定のエラーに遭遇した最初の人でした!
user1118321

6

C標準では、他のプログラミング言語とは異なる方法で「左辺値」や「オブジェクト」などの多くの用語を使用しており、コンパイラメッセージはそのような用語で記述されることがよくあります。用語の使用は規格の一部で一貫性がありませんが、Cを学習したい人はC89、C99、および/またはC11規格のドラフトとそれらの根拠文書を参照する必要があります。「C99ドラフト」や「C89の理論的根拠」などを検索することは非常にうまくいくはずですが、期待するドキュメントを取得する必要があるかもしれません。ほとんどのコンパイラはC99標準をサポートしていますが、C89標準との違いを知っておくと役立つ場合があります。


11
C標準は非常に高密度で重いテキストです。初心者はそれを理解する機会がありません。
-NieDzejkob

4
@NieDzejkob:コンパイラーが使用する用語(質問の目的と思われる)は、標準から派生しています。規格の一部が理解できないことは正しいですが(一部は委員会によって設計されており、著者はその一部が何を意味するのかについて一貫した理解を持っていないようです)、しかし何を理解したい人は「左辺値」のような用語は、それらがどこから来たのかを知っているべきです。さらに、なぜx=0x1e-xエラーが発生するのかを理解したい場合、標準以外は本当に知りません
...-supercat

3
私は@NieDzejkobに同意します。C標準は、初心者と対wantし​​たい種類のテキストではありません。初心者は、積極的な実地体験を早く必要とします。そして、彼らはポップアップしながら新しいものを一つ一つ学ぶ必要があります。標準や理論的根拠を読むのに時間がかかりすぎて、初心者に情報を完全に積み込みすぎてしまいます。
cmaster

2
@cmaster:私は何年も前にC89 Standardで始めましたが、便利な「テキスト検索」機能を備えたブラウザが登場する前からそれほど悪くはありませんでした。後の基準がますます悪化していることを認めます。誰もが標準を唯一の参照として信頼するべきではありませんが、マイクロコンピュータコンパイラの動作に関する民衆の知恵と、標準が低品質の動作を許可する方法との間の相違を認識することが重要です。後者に対処する。
-supercat

3
@cmaster:いずれにせよ、Cをプログラミングしている人は、標準を認識し、必要に応じて、たとえすべてを読み込もうとしない場合でも、標準を参照する方法を知っている必要があります。たとえば、標準ライブラリ関数のWeb検索を行う場合、標準の観点から、それらのコーナーケースが未定義の動作を呼び出すことを言及せずに、一部のコーナーケースで1つの実装の動作を説明する参照を見つけることができます。同じように動作しません。代わりに標準を検索すると、その問題を回避できます。
-supercat

5

誰も明白な答えを出さなかったことに驚いています。実際に最も頻繁に使用されるのは、エラーメッセージを読まないでください。

ほとんどのエラーメッセージの価値の大部分は、単にそのような行で何かが間違っているということです。ほとんどの場合、私は単に行番号を見て、その行に移動します。その時点でのエラーメッセージの「読み取り」は、通常、目をつぶっただけでなく、目を引くものです。行またはその近くで何が間違っているかがすぐにわからない場合は、実際にメッセージを読みます。このワークフローは、その場でエラーを強調表示するIDEまたはツールを使用するとさらに良くなり、小さな変更のみを考慮するというカールビーレフェルトの提案を自動的に実行します。

もちろん、エラーメッセージは常に適切な行を指しているわけではありませんが、適切な根本原因も指し示していない場合が多いため、エラーメッセージを完全に理解することでさえも助けになりません。適切な行を見つけることに関して、どのエラーメッセージがより信頼できるのかを知るのに時間はかかりません。

一方で、初心者が犯す可能性が高いエラーのほとんどは、コンパイラーの助けを必要とせずに、経験豊富なプログラマーにとって痛々しいほど明白です。一方で、初心者にはそれほど明白ではありません(多くの人が明白になりますが、ほとんどの間違いは愚かな間違いです)。この時点で、私はロバート・ハーベイに完全に同意します。初心者は単に言語に精通する必要があります。これを避けることはできません。なじみのない概念を参照している、または意外と思われるコンパイラエラーは、言語の知識を深めるためのプロンプトと見なされるべきです。同様に、コンパイラーが文句を言っているのに、コードが間違っている理由がわからない場合も同様です。

繰り返しますが、コンパイラー・エラーを利用するためのより良い戦略が必要であるというロバート・ハーベイに同意します。上記のいくつかの側面を概説しましたが、Robert Harveyの答えは他の側面を提供します。あなたの友人がそのような「用語集」で何をしたいのかさえ明確ではなく、そのような「用語集」が実際にあなたの友人にとって大いに役立つことはほとんどありません。コンパイラーのメッセージは、言語1の概念を紹介する場所ではないことは確かであり、「用語集」はそれほど良い場所ではありません。エラーメッセージの意味が明快に説明されていても、問題を修正する方法はわかりません。

1 ElmやDhall(およびおそらくRacket)のようないくつかの言語、および言語のいくつかの「初心者向け」実装は、これを試みます。このように、異なる実装を使用するというMSaltersのアドバイスは直接関連しています。私は個人的にそのようなことは説得力がなく、正しい問題に向けられたものではないと感じています。これは、より良いエラーメッセージを作成する方法がないと言うことではありませんが、私にとっては、コンパイラの信念とそれらの信念の基礎を明確にすることを中心に展開する傾向があります。


4

それでは、初心者プログラマはコンパイラエラーメッセージを理解するという課題にどのように取り組むべきでしょうか?具体的には、CとGCCの組み合わせで?

友だちに、理解できないエラーが発生したときに次のことを行うように伝えます。

  • 最後の正常なビルド以降に追加されたコードを削除/コメントします。
  • その小さな部分を元に戻してコンパイルします
  • エラーが発生するまで繰り返します

コンパイラーのエラーは、コンパイラーがコードについて理解していないことのみを伝え、コードの何が問題なのかを知らせません。このアプローチは、エラーをグーグルで調べていくつかのドキュメントまたはStackOverflowの投稿を読むのとほぼ同じ時間を要しますが、あなたが間違っているのが何であるかをよりよく理解できます。

また、ビルドに数分かかるプロジェクトで作業を開始するまで、頻繁にコンパイルします。他のコードを追加しすぎる前にエラーを見つけると、非常に役立ちます。

最後に、一度に1つの作業を行うように指示し、間にコンパイルせずに複数のファイルで作業しないでください。一度に複数の依存関係を導入しないでください。


4

別の手法として、友人がさまざまなエラーメッセージに遭遇したときに、時間をかけて独自の用語集を作成する方法があります。多くの場合、何かを学ぶための最良の方法はそれを教えることです。もちろん、用語集が完成する頃には、おそらく彼はそれをもう必要としないでしょう。

GCCでの私の個人的な経験では、各エラーメッセージは「通常の」一連のミスに関連しています。たとえば、GCCが「&を忘れた」と言った場合、通常は括弧を忘れていたことを意味します。もちろん、どのエラーがどのエラーメッセージに対応するかはプログラマーに依存します。これは、友人が自分の用語集を書くもう1つの正当な理由です。


1
このドキュメントには、(5〜10個のエントリしかない場合でも)オンラインにできるという非常に重要な副次的な利点があり、インターンシップを申請する際の大きな差別化要因になります。
ジョシュランブー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.