わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

「配列変数」と「&配列変数」

ここが変だよC言語 - わさっきで付箋箇所のリクエストをいただき,さらに著者の一人からメールで問い合わせがありましたので,昨日,本を確認しました.
読みながら,なんでこんなところにつけたのか,分からないものは,付箋を外しました.逆に,付箋をつけたところもあります.
昨日付箋をつけたところから,一つ.
上p.160にあるarray09.c*1ですが,手元の環境では,2行目の出力は

size of &a    = 4 bytes

となりました.コンパイラは「gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)」です.コンパイルオプションに,-std=c99,-std=gnu99,-ansiなどを入れても,みな同じ結果でした*2
このプログラムを追試したきっかけは,数ページあとの,以下の記述でした.

「aと&aは同じで配列の開始アドレスである」とはダブルスタンダードもはなはだしい.&a[0]が開始アドレスを返すのは自然である.』
(p.164)

この主張で,aはポインタ値として使用されている配列変数*3という前提があります.そのもとで,「同じ」には同意できません.これ,直感に合いませんThat's against my instinctというのも,aと&aについて,アドレスの値は等しいのですが,型が異なるからです.char a[100];と宣言した場合,char *b = a;そしてchar (*c)[100] = &a;と代入することができますが,このaと&aを逆にすることはできません.
なので,「配列変数」と「&配列変数」は,別物ととらえるべきです.
著者は,array09.cの実行結果を根拠として,aと&aを「同じ」とみなしています.この問題,処理系依存でしょうか.
もうひと工夫.array09.cの途中に

printf("size of (&a)[0] = %d bytes\n", sizeof((&a)[0]));

を追加すると,この出力は

size of (&a)[0] = 100 bytes

でした.「(&a)[0]」とaが同じであること,そして&aとaが異なるものであることの傍証になる*4と思います.

*1:http://www.spacesoft.co.jp/download/books/strangeC/array.htmlからダウンロードできます.

*2:Cygwingcc 3.4.4でも,同じでした.著者様より,bccでは100 bytesになるという連絡をいただきました.

*3:sizeofのオペランドではないということです.

*4:私の実行環境では,という条件がつきますが.