2018年7月28日土曜日

C言語疑問とメモ:多次元配列は何故メモリ上で並んでいると言えるか

以下の内容は個人的メモであり、誤りが含まれている可能性があります。ご注意ください。
CについてはN1570を、C++についてはN3337を参照しています。

多次元配列は何故メモリ上で並んでいると言えるか(int[3][5])(ここでは可変長は考えない)
基本的には「多次元配列の宣言は宣言構文上、配列の配列(Array of array)の宣言である」からだと思う。
(6.5.2.1)に値を参照する場合の説明がある。

その他の前提となりそうな知識
配列とはオブジェクトの連続した(=隙間ない?)並びである。(6.2.5p20)
さらに、(6.2.6.1)より、オブジェクトはバイトの連続した並びである。
E1[E2] は (*((E1)+(E2))) と等しい。(6.5.2.1p2)

先頭要素へのポインタに+1すれば次の要素になることはどこで保証されている?
(6.5.6p8)で保証されると思う。

負の要素がないことはどこで保証する?
配列の要素数は1以上(6.7.6.2p1)と(6.5.6p8)の順序付けによって保証できそう。

配列のサイズ=要素数で良いのか?
(6.7.6.2p1)によれば、配列の宣言で指定しているのは配列のサイズである。
規格書が完璧に書かれていると考えれば、
* sizeofはオペランドのサイズを(バイト単位で)返す。サイズはオペランドの型で決まる(6.5.3.4p2)
* sizeofを配列型を持つオペランドに適用した場合、配列内の総バイト数を返す。(6.5.3.4p4)
であるので、「サイズ!=要素数」と考えたくなる。
そして、配列がオブジェクトの隙間ない並びであると考えれば、要素数はサイズによって決定できると言えそう。
ただ、「要素数を決めることはサイズを決めることである」というのは自明なことであって、わざわざそこまで厳密に書いていないのかもしれない。

規格書を引く場所を間違っているのだろうか?
この点については、C++はしっかり書いてくれている。(8.3.4p1)
ただ、C++では「boundを指定する」、という表現であるので、Cで「サイズを指定する」、というのは正しい表現なのかもしれない。

その他
無理にC言語を使わずに、C的な書き方をする場合でもC++を使ったほうが楽かもしれない。 C++の(3.9p4)のようなわかりやすい表現がCにもあればよいのに。

0 件のコメント:

コメントを投稿