C を勉強し始めたとき,こんな感じで共用体を使って,IP アドレスのうち特定のバイトとかを取り出すみたいな技法があるのを知って,妙に感心していた.
struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; };
その印象が強かっただけに,ANSI C では,共用体のメンバのうち最後に書き込んだもの以外の値は不定である,ってのを初めて知ったときは結構衝撃だったのを覚えている.
とかいうことを思い出しながら,FreeBSD の in.h なんか開いたりしたんだけど,あれ? 何か違う.
struct in_addr { in_addr_t s_addr; };
どうやら 4.4BSD から持って来た時点で既に共用体じゃなかったようだ. Solaris なんかは最近でも共用体になっていて,ただしコメントで S_addr 以外は obsolete だ,てなことが書いてある.そのちょっと前にこんなコメントもあるので,どうやら 4.2BSD の頃は共用体だったっぽい.
/* * IPv4 Internet address * This definition contains obsolete fields for compatibility * with SunOS 3.x and 4.2bsd. The presence of subnets renders * divisions into fixed fields misleading at best. New code * should use only the s_addr field. */
(http://cvs.opensolaris.org/source/xref/usr/src/uts/common/netinet/in.h?r=1.1)
共用体じゃなくなった経緯はこの辺に説明がある.特に ANSI では不定だから,とかいう理由ではないっぽい.
はて,この技法ってそもそも何で知ったんだっけなあ.何かの本か雑誌の記事だとは思うんだけど.
最終更新時間: 2009-01-04 15:31