エンディアンにまつわるエトセトラ

エンディアンうそつかない。

教えて!goo エンディアンを知るには

リトルエンディアンのマシンで作ったバイナリデータをいろいろなマシンで読み込みたいのですが、一部がビッグエンディアンなので変換の必要があります。ただ、ソースを共通にしたいのでエンディアンを知ることができるマクロの値でエンディアンの違いの処理を行いたいのですが、どのようなマクロを使えばいいのでしょうか?

複数プラットフォームで共通のソースを使うために、コンパイル時にエンディアンを吸収したいとうことで。

エンディアン問題をメモリ上の2バイト以上のデータの配置問題と考えれば、極端な話、メモリ上に配置するデータをすべてバイト単位(例えばchar)で格納すれば問題は起きないのです。もちろん冗談です。

intやshortをそのまま格納するとき問題が生じます。しかも格納~取出が同じエンディアンで行われるときには全く問題になりません。当然ながら。

問題になるのは、あるエンディアンで格納したバイト列を別のエンディアンで取出す場合のみです。

で、バイト列上にどんなエンディアンで配置するかをプラットフォームにかかわらず統一するとき、バイト列上と異なるエンディアンのプラットフォームではオーバーヘッドは避けられません。

これはネットワークの世界でも当然のことで、リトルエンディアンのマシンはすべてアドレスをひっくり返すオーバーヘッドを受け入れています。組み込み系のマイコンベースの特殊なプロトコルでリトルエンディアンを見かけるのは、このオーバーヘッドを看過できないからなのかもしれません。それよりもゼロコピースタックを実装したほうがいいと思ったりしますが。また逆に携帯電話やネットワーク機器でビッグエンディアンのMPUが重宝がられるのも当然なのかもしれません。そういう視点で見れば。(実際にはMIPSもARMも各社の実装ではバイエンディアンなわけですが。)

さて、ネットワークが関係なくても、プラットフォーム間で共通に用いるバイナリデータのエンディアンを共通化したければ、やはりオーバーヘッドを無視できません。何しろほぼ全データでエンディアン変換が生じますので。

ここまで書けば、ソース上でエンディアンを識別することが虚しく思えてくるはずです。

いくらソース上でコンパイル時にエンディアンが判別できたからといって、エンディアン変換を避けられないのですから、エンディアンの違いを吸収することは出来ません。エンディアン変換アドレッシングのロードストア命令でも搭載していない限りは。

オーバーヘッドが許されないのであれば、バイナリデータをあらかじめリトルエンディアンビッグエンディアン用それぞれ用意しなければならないでしょう。

そしてネットワーク関連では、リトルエンディアンのプラットフォームではオーバーヘッド分を見積もらなければならないでしょう。

<愚痴>

ベテランさんがときどきこういう話をしているのを耳にします。すくなくとも3回聞きました。

世界がはじまったとき、ビッグエンディアンしかなかった。(モトローラによる創世)

後になってマイコンが出てきて、のし上がってきて、のさばってきたせいで、世界の均衡が崩れた。(電卓戦争)

ネットワーク世界は、かろうじて守られた。(ネットワークバイトオーダーという約束の地)

まぁこんな与太話を若者の脳に植えつけるような人たちが担っていたため、インテルの躍進を許してしまったのでしょう。モトローラも災難ですな。

<余禄>

愚痴にも書いたように、エンディアン問題について騙る人々は多いわけですが、細かい点を確認しておきます。

データ0x1234をメモリに格納したとき、若いアドレスから順に

リトルエンディアン→0x34,0x12と並ぶ

ビッグエンディアン→0x12,0x34と並ぶ

この例を見せたときに、

リトルエンド、なのにどうして下位バイトがに来るんです?

逆にビッグエンドなら上位バイトが後ろに来るんじゃないんですか?

という若者の問いに答えられますか?

これについては原典に当たる必要があります。つまりスイフトのガリバー旅行記です。スイフトといってもスズキの軽自動車ではありません。

物語中でリトルエンディアンとは、『卵の細い(尖ったほう)を先に割るべきであると主張する』一派のことです。逆にビッグエンディアンは『太いほうを先に割る』一派ということになります。そういう各派の対立を皮肉交じりに描いているわけです。

つまりlittle-endとは、「細いほう」、big-endとは「太いほう」を指すだけであり、問題定義が「どちらを先に割るか」なので、コトバ自体には現れないのです。

# endには漢字の「端」と似た用法があります。例:dead end

したがって、エンディアンについての説明では、「とくに根拠はない。しいて言えばスイフトが決めたのを誰かが拝借した。」のみが正しい説明です。

この誰か、についてはまだ調べてません。

(2007.09.05追記)

ガリバー旅行記を書いたスイフトの紹介

http://www.maxmon.com/1726ad.htm

ここにDanny Cohenさんの有名な記事に関する記述があります。1980年。

http://www.shsu.edu/~csc_tjm/fall2001/cs333/ien-137.html

ON HOLY WARS AND A PLEA FOR PEACE

中身見てませんが、LSB/MSBで思い出しましたが、ハード屋さんはエンディアンの話を聞くと不機嫌になる人もいるので気をつけたほうがいいですよ>ソフトやさん。

理由は自分で考えてみることです。