二次元配列とconst修飾子

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Ohagi
記事: 31
登録日時: 3年前

二次元配列とconst修飾子

#1

投稿記事 by Ohagi » 3年前

コード:

#include <stdio.h>

print_array(const int n[10][10])
{
  /* n[][]の中身を表示 */
}

int main(void)
{
  int n[10][10];
  
  print_array(n);

  return 0;
}
print_array()がint n[][]の値を変更しないことを明示するためにconstを付けて定義すると
: warning: passing argument 1 of ‘print_array’ from incompatible pointer type print_array(n);
と表示されます。

clコンパイラだと問題なく通るのですが、gccですと警告されます。

何が駄目だったのでしょうか?

参考書の説明ではconstはこういう修飾子だったようなきがするのですが...

回答の方をお願いします。

hoge

Re: 二次元配列とconst修飾子

#2

投稿記事 by hoge » 3年前

これは残念ながら、Cの仕様です。
通常、関数に配列を渡すとき、関数内で配列を変更しないとき、constを付けることは望ましいことなのですが、
void func(type n[]);
↑このような関数でconstを付けられるのはtypeに対してだけです。
print_arrayの場合にはconstを付けてもいいのはintではなくint [10]になるのですが、
不幸なことにint [10]にconstを付ける方法がCには存在しません。

かずま

Re: 二次元配列とconst修飾子

#3

投稿記事 by かずま » 3年前

kazuki2655 さんが書きました:clコンパイラだと問題なく通るのですが、gccですと警告されます。
gcc --version でバージョンの確認をお願いします。

gcc 4.8.4 では、その警告が出ましたが、
gcc 5.3.0 では、その警告が出ませんでした。

print_array(const int n[10][10]) という宣言は、
print_array(const int (*n)[10]) という宣言と同じです。

main で宣言されている n の型は int[10][10] です。
print_array を呼び出すときの引数 n は、int (*)[10] に型変換されます。
int (*)[10] と const int (*)[10] の型が異なるので、gcc 4.8.4 では、
incompatible pointer type だという警告を出したのでしょう。

一次元配列の場合を考えてみましょう。

コード:

void print_array(const int n[10])
{
  /* n[]の中身を表示 */
}
 
int main(void)
{
  int n[10];
  print_array(n);
  return 0;
}
この場合、呼び出し側の n の型は int *。
関数の宣言の引数 n の型は const int *。
型は異なりますが、型 T へのポインタは、型 const T へのポインタに変換できるので、問題ありません。

二次元配列の場合の int (*)[10] は、型 T が int [10] であり、その型へのポインタです。

int [10] に const をつける記法がありません。
const (int [10]) や int [10]const はダメです。
const int [10] や int const [10] とすると、それは、int を const で修飾したのであって、
配列 [10] を const で修飾したことになりません。

gcc 5.3.0 で、なぜ警告を出さなくなったのかは知りませんが、
警告なしでも問題にならないからでしょうか。

Ohagi
記事: 31
登録日時: 3年前

Re: 二次元配列とconst修飾子

#4

投稿記事 by Ohagi » 3年前

型の変換や修飾などの知識が甘くて完全には理解できませんしたが
C言語の仕様の問題で2次元配列のconst修飾ができないことはわかりました。

今後Cを使っていくうえで2次元配列でconstが使えない理由が気になった時
もう一度読み返させて頂こうと思います。

回答してくださった御二方、ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る