• ベストアンサー

リトルエンディアン、ビッグエンディアンについて

リトルエンディアン、ビッグエンディアンについて 質問があります。 (1)簡単にそのPCがリトルエンディアンなのか、ビッグエンディアン  なのか、分かる方法はありますか?  簡単なCプログラムを書いてメモリ状態をダンプするのが、  一番早いのでしょうか?  それとも、Intel系?モントローラ系?CPUにはあまり詳しくないので、  分かりませんが、これらのどちらかに属していれば決められるので  しょうか?ほかの系とかあるのかな・・・ (2)ネットワークプログラミングをするときに、ビッグエンディアンの  マシンからデータを送出する場合には、htonlなどの関数を使用しなく  ても問題ありませんでしょうか?(ネットワークバイトオーダが  ビックエンディアンであるため)

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

(1) エディアンの判定プログラム short s; char *cp; s=1; cp=(char *)&s; if (*cp) { printf("リトルエディアン\n"); } else { printf("ビッグエディアン\n"); } (2) 移植性を考えるなら「実行環境がどうであっても、ネットワークに送出する段階で、ビッグエディアンでデータを並べるようにコーディングする」のが良いでしょう。 つまり、リトルエディアン、ビッグエディアンどちらのマシンでコンパイル&実行しても、ビッグエディアンでデータを送出するように書く事になります。 言い換えれば「リトルエディアン環境でコンパイル&実行するとビッグエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない」と言う事です。 そして「リトルエディアン環境でコンパイル&実行するとビッグエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「htonl関数そのもの」なのです。 まとめると「移植性を考えるなら、htonl関数が何もしないと判った上で、htonl関数を呼ぶ」と言う事です。 で、ビッグエディアンのマシン用のコンパイラは、htonl関数は #define htonl(a) (a) とかって定義してあったりして「マジに何もしない」ようになってたりします(笑)

upanepa
質問者

お礼

ご回答ありがとうございます。 コンパイルの時点で、エンディアンを変換するか どうかが決まるのですね。実行時に決まるのかと 思っていました。 エンディアンが異なっても、ソース互換があるという ことですね。(バイナリ互換ではない) 勉強になります。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

「普通」の処理系なら #3 のコードで判定できますが, ISO C の枠内でいくと判定できない可能性があります. sizeof (short) == 1 である環境の可能性が捨てきれません. まあ, ワードマシンで「エンディアン」を考えてもしょうがないという指摘はありですが, 理論的には「移植性のある (= ISO C の枠内で確実な) 判定方法は存在しない」ということで.

upanepa
質問者

お礼

ご回答ありがとうございます。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

追記。 当方の回答で 「リトルエディアン環境でコンパイル&実行するとビッグエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「htonl関数そのもの」 と言いました。これは「送出時の観点」から書いた物です。 「受信時の観点」から書けば 「リトルエディアン環境でコンパイル&実行すると、ビッグエディアンからリトルエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「ntohl関数そのもの」 となります(関数名が違う事に注意) つまり 「送出時は、htonl関数を呼んで送出する」 「受信時は、受信してからntohl関数を呼ぶ」 と言う事になります。 そういう訳で、htonl関数、ntohl関数とは「ネットワークバイトオーダーとローカルバイトオーダーを変換する関数のセット」と言う事になります。 そしてこれは「htonl関数、ntohl関数を呼んでさえおけば、実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言う事を意味します。 この「実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言うのが、ANo2の方が書いた >htonlを使った方が、簡単なはずです。 の「簡単」の意味です。

upanepa
質問者

お礼

分かりやすい説明ありがとうございます。 とても勉強になりました!

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.2

> (1)簡単にそのPCがリトルエンディアンなのか、ビッグエンディアン >  なのか、分かる方法はありますか? リトルエンディアン・ビッグエンディアンがどう言ったものであるか 理解しているなら、その判別プログラムも簡単に書ける事でしょう。 分からない場合は、ウェブで調べると良いです。 たぶん、すぐ見つかります。 ・Wikipedia http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3 > (2)ネットワークプログラミングをするときに、ビッグエンディアンの >  マシンからデータを送出する場合には、htonlなどの関数を使用しなく >  ても問題ありませんでしょうか?(ネットワークバイトオーダが >  ビックエンディアンであるため) htonlなどの関数を使わなくても、ネットワークプログラミングをする事は、 可能では、ありますが、htonlを使った方が、簡単なはずです。 参考までにサンプルコードを挙げてみます。 ---------------------------------------------------------------------- #include <stdio.h> int main(int argc, char *argv[]) {   union   {     unsigned short shortValue;     unsigned char charValue[2];   } endianTest;      endianTest.shortValue = 0x0102;   if (endianTest.charValue[0] = 2)   {     printf("is LittleEndian\n");   }   else   {     printf("is BigEndian\n");   }      return 0; } ---------------------------------------------------------------------- エンディアンの判別プログラムは、こんな感じです。

upanepa
質問者

補足

ご回答ありがとうございます。 判定プログラムありがとうございます。 すごく分かりやすいです。 一点質問なのですが、 >htonlを使った方が、簡単なはずです。 これは具体的にはどのような意味なのでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

Intel だけど Itanium はバイエンディアン (つまりビッグエンディアン, リトルエンディアンのどっちも使える) です. 他にもいくつかバイエンディアンの CPU があったような気がする. 極端なやつだと「プロセスごとにエンディアンが決められる」ものすらあったような.... ということで, ビッグエンディアンと決めつけるのは危険だと思います.

upanepa
質問者

お礼

ご回答ありがとうございます。 >ビッグエンディアンと決めつけとるのは危険だと思います. 将来の移植なども考慮すると、常にhtonlなどを使用して プログラミングしたほうがよいかもしれないですね

関連するQ&A

専門家に質問してみよう