何故駄目なのか?

C言語で配列に配列を代入するのは何故駄目なのか

C言語で配列に配列を代入すると、コンパイルエラーが発生します。例えば以下のコードをgccコンパイルしようとすると、"incompatible types in assignment"というエラーが発生します。

/* header files */
#include <stdlib.h>
#include <stdio.h>
     
/* main */
int main (int argc, char *argv[]) {
    char c1[] = "afa";
    char c2[4];
     
    c2 = c1;
        
    return EXIT_SUCCESS;
}
|10| error: incompatible types in assignment


"incompatible types in assignment"とは、"互換性のない型に代入をしようとしている"という内容のエラーです。
char型の配列に、同じchar型の配列を代入しようしているのに互換性のない型だと怒られる。これは奇妙な話です。

何故駄目なのか

その理由を理解するためには、まず、C言語の右辺値と左辺値を知る必要があります。

右辺値と左辺値

例えば次のようなコードがあったとします。

int x = 100;
x = x + 1;


初心に返って考えると、これはxという箱の中に入っている値を+1して、その結果をxという箱に格納するコードです。
つまり、左辺のx(左辺値)はxという箱を表し、右辺のxは100という値を表しているわけです。
これを一般化してまとめると以下のようになります。

  • 左辺値: 変数の領域そのものを表す
  • 右辺値: 変数の中身表す


配列の格下げ規則


さて、本題の配列についてですが、配列の右辺値と左辺値は、普通の変数のそれとは少し異なります。
結論からいってしまえば、配列の左辺値は、配列の領域全体を意味し、
右辺値は、配列の先頭要素の置かれてる領域を意味します。
これを図で表すと以下のようになります。


配列は右辺値になると、配列から「配列の先頭要素の置かれてる領域」という意味に格下げになります。
これを配列の格下げ規則といいます。

配列に配列を代入するのは何故駄目なのか(結論)


配列の格下げ規則によって、配列の領域全体を表す変数に配列の先頭領域を格納しようとしてしまいます。
これによって、「互換性のない型に代入しようとしているよ」とコンパイラに怒られるというわけです。