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


データ型やポインタに関する compile time error を少し解説しておきましょう。 紹介するのは、データ型の不一致に関するものです。 型不一致のエラーは、なにかとうるさく聞こえるでしょうが、 プログラム上の書き間違い、ミスを指摘してくれている事が多いです。 しっかり耳を傾けましょう。 とりあえず、 強制型変換(cast)を行って目を背ける、などということはしないほうがいいです。

データ型の不一致

サンプルコードを例に各種の error を眺めてみます。

int* と char * の混合

argv[0] などは char* という型で、 一方で int * と混ぜて使っており混乱したことになっています。
 7:int main(int argc, char** argv) {
 8:    char * firstArg = argv[0];
 9:    int * secondArg = argv[1];   互換性のないpointerによる初期化
10:    if(strcmp(firstArg, secondArg) == 0) { 非互換なpointerが第2引数に
11:        secondArg = argv[2];     互換性のないpointerによる代入
12:    }
/*data_P.c: In function `main':
  data_P.c:9: warning: initialization from incompatible pointer type
  data_P.c:10: warning: passing arg 2 of `strcmp' from incompatible pointer type
  data_P.c:11: warning: assignment from incompatible pointer type
 */

pointer データと整数値との混合

 7:int main(int argc, char** argv) {
...
14:    argv[3] = 3; 代入によって integer が cast なしに pointer に変換
/*
 * data_P.c:14: warning: assignment makes pointer from integer without a cast
 */

多次元配列の型の不一致

例えば、int[2][2]という多次元配列の場合、 int[2]が並んだ配列(あるいはint[2]データへのポインタ)です。 一方で、int[2][3]ならint[3]が並んだ配列(あるいはint[3]データへのポインタ)です。 というわけで、各要素のサイズが違う場合は、混ぜて使うと困ったことになります。 というわけで、warning がでます。

 3:void foo(int parray2x2[2][2]) {
 4:    parray2x2[1][0] += 4;
 5:}

16:    { /* main関数の中 */
17:        int array2x2[2][2];
18:        int array2x3[2][3];
19:        int array3x2[3][2];
20:        foo(array2x2);  型は一致
21:        foo(array2x3);  型は不一致
22:        foo(array3x2);  int [][2] であれば、一致
23:    }
/*
 * data_P.c:21: warning: passing arg 1 of `foo' from incompatible pointer type
 */

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