コンピュータを使う上で、エラーメッセージというものは避けられないものです。 大抵の人は見るのも嫌でしょう。しかしエラーメッセージには、なぜエラーになっ たかという情報が含まれています(エラーメッセージの意味がわかりにくい、不 親切なプログラムも中にはありますが)。エラーメッセージが出た場合、 見慣れないものであっても(英語であっても)、とりあえず読んでみることが大 切です。
コンパイラは
gcc
を使います。しかし、コンパイラのエラーメッセージは専門的な用語も多く、
入門者にとっては理解しにくいものもあるでしょう。ここでは gcc での典型的
なエラーメッセージと、その解決法について説明します。なお、このページは
gcc version 2.95.2 に基づいています。
現在使用している物とメッセージが違う場合はどんどん指摘して下さい。
コンパイルをしたときに、例えば以下のようなメッセージが出たとします。
% gcc foo.c foo.c: In function `main': foo.c:3: `i' undeclared (first use in this function) foo.c:3: (Each undeclared identifier is reported only once foo.c:3: for each function it appears in.)
まず、左端の foo.c というのは、エラーがあるファイルの名前で
す。次の 3 というのは、エラーのある行数です。つまり、foo.c
というファイルの 3 行目にエラーがあるということになります。
また、エラーメッセージの最初の行の In function `main':
というのは、「以下のエラーは main 関数の中で発生しました」
という意味です。
また、学習が進むにつれて main 関数以外の関数も作るようになります。
その時ここに表示される関数名は、エラーを見つけるのに重要な役割を果たします。
コンパイルすると、エラーメッセージが山のように出てくることがありますが、 基本的には一番最初のエラーから修正していきます。最初のエラーが原因で 他の箇所でもエラーになることもあり、最初のエラーを修正するだけで、他のエ ラーも全部消えることはよくあることです。
以下では、典型的なエラーメッセージについて見ていきます。 もし見慣れないエラーメッセージが出たら、ここを参考にプログラムを修正して みてください。なお、このページのサンプルプログラムの左端の数字は行番号を表 すもので、プログラムの一部ではありません。
1 #include <stdio.h>
2 int main(){
3 for(i=0; i<10; i++){
4 printf("%d\n", i);
5 }
6 }
% gcc undeclared.c undeclared.c: In function `main': undeclared.c:3: `i' undeclared (first use in this function) undeclared.c:3: (Each undeclared identifier is reported only once undeclared.c:3: for each function it appears in.)
これはプログラム中で使っている変数が宣言されていない場合に起こります。 関数の始めなどで、その変数を宣言してあげてください。 また、長い名前の変数や綴りが難しい変数では、タイプミスをしている可能性も あるので、その点も充分にチェックしてください。
1 #include <stdio.h>
2 main(){
3 int i;
4
5 for(i=0; i<10; i++){
6 printf("%d\n", i);
7
8 }
% gcc parse.c parse.c: In function `main': parse.c:9: parse error at end of input
9 行目でエラーとなっていますが、実際は 7 行目に } がないのが
原因です。このエラーは大抵の場合、括弧の閉じ忘れか、括弧が2バイト文字
(俗に言う全角)だったりします。どこで括弧の対応がおかしくなっているかは、
エディタのインデント機能(emacs の M-x indent-regionなど)
を使うと探しやすいです(括弧の対応がおかしい部分でインデントがずれる)。
1 #include <stdio.h>
2 int main(){
3 int i;
4
5 for(i=0; i<10; i++){
6 printf("%d\n", i)
7 }
8 }
% gcc parse-before.c parse-before.c: In function `main': parse-before.c:7: parse error before `}'
"parse error before" 関連のエラーが出た場合は、エラーがになった行の前の
行も確認しましょう。また、} 以外だけでなく、他の文字が入る
こともあります。その文字の前に間違いがないか調べてみてください。
この例では、6 行目の最後の ; が抜けてい
ます。また、その } に対応する { が抜けている場
合もあるので、確認しましょう。
1 #include <stdio.h>
2 int main(){
3 int i;
4
5 for(i=0; i<10; i++){
6 printf("%d\n", i);
7 }
8 }
% gcc invalid-char.c invalid-char.c: In function `main': invalid-char.c:5: parse error before character 0241
一見、どこにエラーがあるのか分かりにくいですが、このエラーが出た場合は 全角の文字が紛れ込んでいる可能性があります。この例では、5行目の最後に 全角スペースが入っています。この他、括弧などが全角になっている場合も、 このエラーが発生します。
1 #include <stdio.h>
2 int main(){
3 int i;
4
5 for(i=0; i<10; i++){
6 printf("%d\n, i);
7 }
8 printf("\n");
9 }
% gcc unterminated.c unterminated.c:8: unterminated string or character constant unterminated.c:6: possible real start of unterminated constant
これは " を閉じ忘れている場合に起きます。
エラーが発生しているのは 8 行目ですが、エラーをよく見ると、
6 行目から間違っていることが読み取れます。ちゃんと "
を閉じてあげてください。
1 #include <stdio.h>
2 int main(){
3 int i;
4
5 for(i=0; i<10; i++){
6 prnitf("%d\n", i);
7 }
8 }
% gcc prnitf.c /var/tmp/cciASwUT.o: In function `main': /var/tmp/cciASwUT.o(.text+0x30): undefined reference to `prnitf' collect2: ld returned 1 exit status
このエラーが出た場合は、大抵関数名の打ち間違いです。この例では、
printf としなければならないところを prnitf
と書いてしまっています。
1 #include <stdio.h>
2 #include <math.h>
3 int main(){
4 double d;
5
6 d=sin(3.1415926);
7 printf("%f\n", d);
8 }
% gcc math.c /var/tmp/ccWDmq5o.o: In function `main': /var/tmp/ccWDmq5o.o(.text+0x10): undefined reference to `sin' collect2: ld returned 1 exit status
これは 「undefined reference to `prnitf'」と
ほぼ同じですが、関数名が sin になっています。
sin()、cos()、tan() など(他にもたくさんあります)の数学関数を使う場合に
は、コンパイルするときに -lm というオプションを付ける必要が
あります。また、#include <math.h> を始めに書くのも忘
れないようにしてください。
% gcc math.c -lm % ./a.out 0.000000
1 #include <stdio.h>
2 int main(){
3 int i;
4
5 scanf("%d", i);
6 }
% gcc seg_fault.c % ./a.out 1 Segmentation Fault
このエラーはメモリに不正なアスセスをした場合に発生します。
ポインタを習うまでは、このエラーが出た場合は大抵 scanf
の引数の & の付け忘れです。この例では、
scanf("%d", i); ではなく、scanf("%d", &i);
とすることにより、正しいプログラムになります。
それ以外でこのエラーが出た場合は、エラー箇所を探すのには苦労することがあ ります。デバッガ(例えば gdb など)を使えば、すぐに見つけることができる ので、 デバッガの使い方 を修得することをお薦めします。
/usr/include/stdio.h の 261 行目の `__va_list' の前で構文エラー
1 /* Here is comment. */
2 /* Here is also comment. */ Here is not comment.
3
4 #include <stdio.h>
5 int main(){
6 int i;
7
8 for(i=0; i<10; i++){
9 printf("%d\n", i);
10 }
11 }
% gcc va_list.c va_list.c:2: parse error before `is' In file included from va_list.c:4: /usr/include/stdio.h:261: parse error before `__va_list' /usr/include/stdio.h:262: parse error before `__va_list' /usr/include/stdio.h:265: parse error before `__va_list' /usr/include/stdio.h:267: parse error before `__va_list'
このエラーが出た場合は、ファイルの先頭の
#include <stdio.h>
の前におかしな文字が入っていなか調べてみましょう。
この例では、#include 文の上にコメントが書いてありますが、
コメント部分以外にもコメントが書かれています。