2016-07-08 5 views
-1

私はコンパイラエラーがバッチで来ることに気付きました。私が作ったとき、私は80のエラーがあるかもしれません。その後、これらのエラーをすべて修正した後、最後のエラーが修正された後、makeを実行し、コンパイラは別の100バッチのバッチをアナウンスします。これは数回発生します。コンパイラはいくつかのラウンドまたはフェーズを経て、それぞれの最後に一連のエラーを生成しているようです。なぜコンパイラエラーはバッチで起こるのですか?

これは、人為的なエラーの制限とは関係ありません。 fmax-errorsはデフォルトでは0です。これはコンパイル時の値です。

この現象の説明は何ですか?

この場合、私はgccを使用していますが、同じことをやっている他のコンパイラに気付きました。

+0

あなたの入力習慣に取り組む必要があると思われます。また、コンパイルの間に何千ものコード行を書いてはいけません。いくつかのコンパイルを書き、コンパイルをいくつか書いてください。下端ではなく、エラーのリストの先頭から開始してください。おそらく1つまたは2つを修正してから、再コンパイルしてください。 –

+0

@dwelchこの特定のプロジェクトは、特有の理由のためにコンパイルが試行される前に、異常に大量のコードが書き込まれてしまいました。通常、私は徐々にコンパイルします。 –

+0

この種の問題は、そのようなプロジェクト、獣の性質に起こります。 1つのターゲットから別のターゲットに適切な大きさのプロジェクトを移植するのと同じように、一度に数千のエラーを1つまたは数つ挽いていくだけです。 –

答えて

1

あなたはそれについて何もすることはできません。

複数の関数定義を含むc(++)ファイルを考えてみましょう。コンパイラは、誤った関数の実装に続いてモジュールのソースコードを完全に解析できない場合があります。多くの場合、エラーにはあいまいさがあり、コンパイラは解決できません。関数の閉じ括弧が欠けているとします。コンパイラは、エラーチェックのためにそれをどのように解釈するのですか?中括弧はそこにあると仮定しますか?または、次の関数が最初の関数内にネストされた関数であり、閉じ括弧がファイルの最後に実際には存在しないと仮定します。

実際には、私はめったに気にしません。なぜなら、ビルドしなければ、プログラムの動作について推論する価値はないからです。最終的にすべてのエラーを1つずつ処理する必要があります。

これに関するコンパイラの開発者の取材は面白いだろう。

+0

それは妥当と思われますが、あいまいです。私は、コンパイルが特定のポイントで停止し、そのエラー配信を行う理由をより具体的に特定することを望んでいます。 –

+0

これは基本的にはファイルが直線的に解析されるのであれば、その行の最後の部分をセミコロンで区切ってその部分を前方に変更したり、閉じ括弧やかっこなどが足りなくなったりします。パーサは、重要な文字が1つもないファイルは、構文解析の観点から見た混乱の総量です。 –

+0

@dwelch私の場合、ほとんどの場合、最終的なエラーはブラケットまたはスコープに影響する構文エラーではありませんでした。 –

0

通常、これは構文エラー(意味エラーとは対照的に)によって発生します。

構文エラーはコンパイラを混乱させる可能性があります。より正確には、内部状態がコードが想定しているものとよく一致しないことがあります。結果は、一見無関係なエラーメッセージのカスケードになる可能性があります。

のgccを使用して小さな例(同様の考察が他のコンパイラに適用する可能性がある):、行方不明{、それはchar*する必要があります(sための間違った種類:

#include <stdio.h> 
int main(void) 
    char s = "Hello, world"; 
    puts(s); 
} 

これは、2個のエラーがありますいいえ。char)。

本当に巧妙なコンパイラは、欠けている部分がどこにあるかを知り、その時点で追加することを提案し、ファイルの残りの部分をコンパイルするために続行します。 GCCのいかなる批判が意図していないが、それはかなりその賢いありません:{なし

c.c: In function ‘main’: 
c.c:3:5: error: parameter ‘s’ is initialized 
    char s = "Hello, world"; 
    ^
c.c:4:5: error: expected declaration specifiers before ‘puts’ 
    puts(s); 
    ^
c.c:5:1: error: expected declaration specifiers before ‘}’ token 
} 
^ 
c.c:2:5: error: old-style parameter declarations in prototyped function definition 
int main(void) 
    ^
c.c:5:1: error: expected ‘{’ at end of input 
} 
^ 

は、char s;の宣言は、実際に古いスタイル(前ANSI)パラメータ宣言として、その時点で構文的に有効になります。 gcc(やや合理的に)はそれが何であるかを前提にしており、イニシャライザについて間違ったタイプについては不平を言っていません。 putsコールは古いスタイルのパラメータリストには表示しないでください。最後にファイルの最後にある{が不足していると不平を言っています。

sという宣言の意図したコンテキストがわからないため、他の問題を適切に診断できません。我々は適切な場所に{を追加した後

、gccが正しく、残りの問題を診断することができます:

c.c: In function ‘main’: 
c.c:3:14: warning: initialization makes integer from pointer without a cast [enabled by default] 
    char s = "Hello, world"; 
      ^
c.c:4:5: warning: passing argument 1 of ‘puts’ makes pointer from integer without a cast [enabled by default] 
    puts(s); 
    ^
In file included from c.c:1:0: 
/usr/include/stdio.h:695:12: note: expected ‘const char *’ but argument is of type ‘char’ 
extern int puts (const char *__s); 
      ^

より複雑なケースでは、あなたがきれいにコンパイルを取得するためにいくつかのパスが必要になる場合があります。その一方で、コンパイラは時々パースを回復して継続することができますが、Cの構文はそのようなリカバリの試みが非常に頻繁に失敗するようなものです。

コンパイラが構文エラーを報告した場合、は最初に報告された構文エラーを修正し、を再コンパイルします。最初の構文エラーの前に複数の非構文エラーがある場合は、先に進んで修正してください。構文エラーに続く診断メッセージは、信頼されないものとします。

これには、構文エラーメッセージの認識方法を知る必要があります(これは100%真実ではありませんが、時にはそのようなメッセージが役立つこともあるので、修正する前に修正して修正する前に問題を指摘することがあります)。コンパイラの中には、エラーメッセージに "syntax"という単語が含まれているものもありますが、gccではそうではありません。 gccがと予想される場合、それは構文エラーメッセージです。

この場合のように、構文エラーメッセージが実際の問題を示していない可能性があります。エラーが報告された箇所から数行(または多くの行)をスキャンして、何が原因かを調べる必要があります。 Cソースファイルの小さなエラーは、それでも文法的に価値のあるものに変えることができます。つまり、はほぼですが、意味は非常に異なります。不足しているセミコロンは、この種の問題の一般的な原因です。不一致のコメント区切り記号は別のものです。

コンパイルする前に構文の誤りを検出するために、構文強調表示付きのIDEやエディタなどの他のツールが役立ちます。

関連する問題