Compile Time Error などの解説 (その 1)


ここでは、簡単に compile が出す error comment をすこし解説しておきます。 思いついたものを書いているので、いろいろ抜けています。 それから、データ構造に関するものは、次回以降に回します。

debug の際は、まずは Syntax Error がなくなるように心掛けましょう。

Syntax Error 関連

プログラムを読込んでいるときに、Syntax が合わないと言って怒るケース。 括弧の対応があっていなかったり、";" を忘れたり ":" と間違えたりといったタイプミスなど 原因はいろいろでしょう。気をつけなくてはいけないのは、コンパイラは正しいプログラムと頑張って 理解していき限界が来た時点で error を出します。ということで、実際の原因はもっと上流に あることも多いです。

例えば、自動インデントにまかせたりするだけで原因が簡単に分かることもありますので、 試してみましょう。 Emacs/Mule だと、region 指定(一方の端で Ctr-SPACE した後、もう一端にカーソルをもっていく)した後で、 M-x indent-region とすると、自動 indent を行ってくれます。 各行毎の indent は、tab でOKです。 ちなみに、Emacs/Mule で XXXX 行目に移動したいときは、M-x goto-line [Return]とした後、XXXXX[Return] とすれば、目的の行番号に移動してくれます。

decl_err0.cの場合

int main(int argc, char** argv) {
    int i;
    int result;
    for(i = 0; i < 10; i++) {
        result += i; /* 本来次の行で括弧を閉じ損ねたのが原因 */
    return result; 
}
/* decl_err0.c: In function `main':
   decl_err0.c:8: parse error at end of input */
decl_err0.cの場合
int main(int argc, char** argv) {
    int i /* 2 行目で ; を忘れたけど */
    int result;
    for(i = 0; i < 10; i++) {
        result += i;
    }
    return result;
}
/* decl_err1.c: In function `main':
   decl_err1.c:3: syntax error before `int'
   decl_err1.c:4: `i' undeclared (first use in this function)
   decl_err1.c:4: (Each undeclared identifier is reported only once
   decl_err1.c:4: for each function it appears in.)
   decl_err1.c:5: `result' undeclared (first use in this function) */

宣言不足に関する error

変数は利用する前に宣言しておかないと error が出ます。 実は、先ほどのでも、syntax error の結果、 int i の宣言が読込めず、
   decl_err1.c:4: `i' undeclared (first use in this function)
   decl_err1.c:4: (Each undeclared identifier is reported only once
   decl_err1.c:4: for each function it appears in.)
「4行目のiは、はじめて使うのだけど、宣言されていないよ」と怒っています。

重複定義に関する error

これは、同じ名前の変数を複数定義しようとした場合に起ります。 これはglobal_varという変数をdecl_err2a.cdecl_err2b.cの両方で定義した場合。 リンクする段階になって、二つの定義が衝突すると怒っています。
kamada@cygwin% gcc -c decl_err2a.c
kamada@cygwin% gcc -c decl_err2b.c
kamada@cygwin% gcc -o decl_err2 decl_err2a.o decl_err2b.o
decl_err2b.o(.data+0x0):decl_err2b.c: multiple definition of `global_var'
decl_err2a.o(.data+0x0):decl_err2a.c: first defined here
collect2: ld returned 1 exit status

型の不一致に関する error

これは、宣言や定義や利用法が衝突する場合です。 サンプルとして、decl_err3.cを紹介します。
int foo(); /* プロトタイプ宣言 */

int bar() { return foo(); }

void foo() { return; } /* 定義の方は、void を返す */
/* decl_err3.c:5: conflicting types for `foo'
   decl_err3.c:1: previous declaration of `foo' */

代入式左辺に関する制限

たとえばこんな場合。
int foo() {
    int y;
    y + 2 = 4;
}

配列初期化の際のサイズに関する制限

配列の初期化の際、サイズは定数でなければ行けません。つまり、こんな ことをしてはいけないわけです(decl_err4.c)。
int n = 3;
int array[n];
/* decl_err4.c:2: variable-size type declared outside of any function */

2001.10.29/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp