web-dev-qa-db-ja.com

初心者プログラマは、コンパイラエラーの用語集がないことに不満を感じています。

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

私自身-経験豊富なプログラマーとして-このような状況に陥ることは非常にまれですが、これらのまれな事態が発生することはありません。私はなんとか検索エンジンでエラーメッセージを探すことでなんとかしますが、明らかにそれは彼にとって常にうまくいくとは限りません-特に彼が遭遇するエラーはより一般的であり、複数の異なるケースで発生します自分の。

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

65
einpoklum

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

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

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

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

この例は、「セミコロンが必要です」、またはパーサーが何か(必ずしもセミコロンではない)でハングアップしたことを示す構文エラーの数です。または、「予期しない前方宣言」のようなエラーです。エラーが発生した場合、それは常に、.hファイルの1つで大文字の使い方が間違っていたが、問題の原因として.hファイルを指していないことを意味します。

あなたの友人の戦略は、これをエラーと解決策のリストにパターンマッチすることであってはなりません。 actual問題が何であるかを理解するには、C言語の構文と仕様を十分に理解する必要があります。

56
Robert Harvey

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

これは特に、最も複雑なタイプのエラーに当てはまります。たとえば、(初心者には珍しいことではない)2つの類似した構成を混在させると、コンパイラは通常、正しいエラーメッセージを生成するときに問題が発生します。これにより、実際に構成Bを意図したときに、コンパイラが構成Aの誤った使用に関するエラーメッセージを表示したときに、混乱が生じる可能性があります。

26
MSalters

誰かが WikibooksのGCCエラー用語集 を試みましたが、うまくいかず、更新されていないようです。

「エラー」セクションは「警告」セクションよりもはるかに進んでいます。それはG ++を目的としたように見えますが、そこにはあなたの友人が使用するための情報がまだある可能性があります。

13
nBurn

上記の回答に加えて、ほとんどのコンパイラーには包括的なエラー用語集がないことに注意してください-これらはメッセージとして維持するのに多くの作業になりますそれら自体はしばしば変化し、それらはかなりたくさんあります。

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

それを超えて、時間と言語とコンパイラに精通しているだけで十分です。それと カールビーレフェルトからの良いアドバイス です。

12
Dúthomhas

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

6
supercat

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

ほとんどのエラーメッセージの価値の大部分は、単にそのような行で何かが間違っているということです。ほとんどの場合、私は行番号を見てその行に行きます。その時点での私のエラーメッセージの "読み取り"は、通常、私の目を通過したものだけであり、スキムでさえありません。ライン上またはラインの近くで何が問題なのかすぐに明らかにならない場合は、実際にメッセージを読みます。このワークフローは、IDEまたはエラーをその場で強調表示するツールを使用してさらに改善され、小さな変更のみを考慮するというカールビーレフェルトの提案を自動的に達成します。

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

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

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

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

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

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

4
Owen

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

理解できないエラーが発生した場合は、友達に次のように伝えます。

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

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

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

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

4
Kevin