てけもぐ Tech 忘備録

error: assignment to expression with array type! 代入出来ません!

対象

C 言語学習者

内容

C の配列に関しては幾つか書いていますが、初学者が配列を使っていて遭遇するであろうこのエラー。

error: assignment to expression with array type

これはなかなかの初心者殺しだと思います。

言っていることは、配列型に代入しちゃだめよ!ってことで単純ではありますけど、ポインタとごっちゃになる人は結構いるハズ。前にも書きましたけど、

配列型はアドレスそのもの!

です。なのでそれへの代入は出来ません。

int main (){
  char array[] = {'a', 'b', 'c'};
  char *ptr = "abc";

  array = ptr; // error!
}

上のコードは error: assignment to expression with array typeとエラーを吐いてコンパイル出来ません(gcc の場合のエラーメッセージ)。

でも逆は出来ます。アドレスを保持するポインタ変数に、アドレスを入れているので。

int main (){
  char array[] = {'a', 'b', 'c'};
  char *ptr = "abc";

  ptr = array; // OK!
}

何故ポインタ型と混同してしまうのか。私からすると以下の2つ。

  1. array[i] とポインタと同様に添字アクセスできること
  2. 関数への引数でポインタ渡しされること

1番目のはいいんですよ。アドレスだって、添字分番地を増減させて中身を取れるのは自然だと思います。

問題は2番目。以下のコードは問題なくコンパイルされます。

void func(char arg[]){
  char *ptr = "ABC"; 
  arg = ptr;  // NO error!
}

int main (){
  char array[] = {'a', 'b', 'c'};
  func(array);
}

ねぇ...(笑)。

中で何やっているかって、関数に渡す時にポインタを作ってそこに array のアドレスを入れて渡してるんですよね。なので、関数の引数のchar arg[]は実はポインタ。だから、func(char *arg) として宣言しても同じ様に動きます。

これ、明確に言われるか、関数呼び出しをアセンブラで理解しないと混乱すると思います。

Tags