In article <squ7k56vv9z.fsf@stellar.co.jp> manmos@stellar.co.jp writes:
>> 構造体のメンバの記憶域は並べられた順に割り当てらることとなっていますが、
>> これには何か理由がありますか。
>ならびが保証されていないと、むっちゃ困りますけど、理解できません?
どう困るか説明しないといけないな、と思いつつ見てたんですが、
どうも本質的なところを突いている回答が出てこないような気が……

そもそも、構造体の歴史的起源ってCOBOLのものだと思うんですが、
(それ以前が存在することを御存知の方は御教示ください)
COBOLの構造体は「ファイル入出力の単位」という性格を
明確に主張する仕様になっています。
そもそも、COBOLは「磁気テープ上のデータを読み込んで、加工して、
別の磁気テープに書き出す」処理を行うという発想で設計されていて、
変数は入出力デバイスにリンクしているのが「フツー」であり、
そうではない「作業用一時変数」は継子扱いです。

このような、構造体の「起源的意義」というのは、
C言語などの新しい言語にも、かなりの部分が引継がれていると思います。
流石に「磁気テープ上のファイル」を強烈に意識した部分は消えていますが、
「当該プログラムと、その外の世界との間」でデータを遣り取りする単位
という発想が残された用法は、現在でも主流でしょう。
ディスクファイルはもちろん、
通信に用いるパケットなどの構造も
構造体で記述してまとめて引き渡すのがフツーだし、
各種ライブラリやシステムコールなどとの間で
構造体の構造情報を共有し、それを前提として
構造体の形でデータを授受するというのは、フツーのことですよね。

例えば、
In article <bi586t$i2n$1@ns.src.ricoh.co.jp> ohta@src.ricoh.co.jp writes:
>struct foo {
>  int a;
>  int b;
>  int c;
>  char s[1];
>};
>のように構造体を宣言しておいて、任意の長さの領域を
>malloc()してからstruct foo *にキャストして使うなん
>てことをむかしのプログラムはよくやってました。つま
>りsに任意の長さの領域を割り当てたいからです。
というのにしても、
可変長のデータ云々は、構造体を用いる本来の目的ではありません。
構造体を用いる理由は「a, b, c, s」という「一組のデータ」を
一斉に授受することです。

こういう場合に、構造体に属するデータを
最も簡単かつ確実に弁別する手段は「並び順による照合」です。
例えば名前による弁別では、名前に関する情報を引き渡す仕掛けが必要になり、
状況によっては、そのことが本質的な障害になって
必要な機能が実現できないことも考えられます。
そこまで行かない場合でも、確実にスループットが低下してしまいます。

「並び順による照合」を前提に考えれば、
コンパイラが勝手に順番を変えたら困ることは自明ですよね。

                                戸田 孝@滋賀県立琵琶湖博物館
                                 toda@lbm.go.jp