第11回
エラーメッセージと対処方法(1)〜エラーの原因を突き止める

1行のズレとシンプルなメッセージ

先のリスト3で出力されるエラーメッセージは、内容がシンプルな上に指摘している行が1行ズレています。何とも不親切な感じがしますが、それには理由があります。

1行ズレた行の指摘

先のエラーメッセージは、“syntax error near 'for'”(for のあたりに構文上の誤りがある)という至ってシンプルなものです。ここで示されている'for'はソースの9行目ですから、「;」を忘れたprintf関数呼び出しの次の行にある2回目(内側)のforループ開始箇所を示しています。

本来なら、「;」が抜け落ちている8行目のprintf関数呼び出しに対して間違いを指摘されるのが自然なように思えますが、Cではえてしてこのような1行ズレた指摘が行われます。それも「syntax error(構文上の間違い)」という何ともぶっきらぼうな内容ですから、はじめてCコンパイラのエラーに接した人は、意味不明で混乱するかもしれません。

ちなみにVisual C++ 2005では、同じミス(;忘れ)に対して以下のようなエラーメッセージが「エラー一覧」ペインに表示されます ※4

エラー1 error C2143: 構文エラー : ';' が 'for' の前にありません。
「;」がないと指摘されているため、LSI-Cの“Syntax error”に比べれば分かりやすくなっています。しかし、示されるエラーの箇所はprintf呼び出しの最後ではなく、やはり『'for'の前』となっています。

メッセージの他にファイル名と行番号も表示され、メッセージをダブルクリックすればエラーの発生した行にカーソルが移動します

1行ズレる理由

エラーの発生した行が1行ズレて指摘される理由は、コンパイラがソースの先頭から順に1行単位でコンパイルしていくためです。コンパイルを行っていくとき、行末に「;」がないとコンパイラは『文はまだ終わっていない』と解釈し、次の行の処理に移ろうとします。

そして、次の行の処理に移ってはじめて“for”という別の(前行から続いていない)命令に接し、その時点で『前の行の最後に;がない』という構文上の間違い(文法エラー)が明らかになります。

Cコンパイラは間違いが見つかった時点でエラーを検知するため、このような場合には問題の箇所の1行下がエラーのあった行とされてしまうのです。

つれないメッセージの理由

つれないメッセージの理由には、Cは基本命令が少なく構文規則が単純であることが挙げられます。

処理の大半がライブラリ関数に委ねられ、さらにプログラマーが独自の関数を作ってプログラムを組み上げていくというスタイルのため、コンパイラ側で検知できるエラーは主に構文規則に関わるものに絞り込まれ、関数の使い方に関するエラーはプロトタイプ宣言に沿った内容だけになってしまいます。

そのような理由で、どの部分がどのようなエラーなのかを具体的に示すことが困難になり、結果、シンプルなつれないメッセージとなってしまうのです。