アプリ版:「スタンプのみでお礼する」機能のリリースについて

リトルエンディアン、ビッグエンディアンについて
質問があります。


(1)簡単にそのPCがリトルエンディアンなのか、ビッグエンディアン
 なのか、分かる方法はありますか?
 簡単なCプログラムを書いてメモリ状態をダンプするのが、
 一番早いのでしょうか?
 それとも、Intel系?モントローラ系?CPUにはあまり詳しくないので、
 分かりませんが、これらのどちらかに属していれば決められるので
 しょうか?ほかの系とかあるのかな・・・


(2)ネットワークプログラミングをするときに、ビッグエンディアンの
 マシンからデータを送出する場合には、htonlなどの関数を使用しなく
 ても問題ありませんでしょうか?(ネットワークバイトオーダが
 ビックエンディアンであるため)

A 回答 (5件)

(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)
とかって定義してあったりして「マジに何もしない」ようになってたりします(笑)
    • good
    • 0
この回答へのお礼

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

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

お礼日時:2008/12/23 00:10

「普通」の処理系なら #3 のコードで判定できますが, ISO C の枠内でいくと判定できない可能性があります. sizeof (short) == 1 である環境の可能性が捨てきれません.


まあ, ワードマシンで「エンディアン」を考えてもしょうがないという指摘はありですが, 理論的には「移植性のある (= ISO C の枠内で確実な) 判定方法は存在しない」ということで.
    • good
    • 0
この回答へのお礼

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

お礼日時:2008/12/23 00:04

追記。



当方の回答で
「リトルエディアン環境でコンパイル&実行するとビッグエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「htonl関数そのもの」
と言いました。これは「送出時の観点」から書いた物です。

「受信時の観点」から書けば
「リトルエディアン環境でコンパイル&実行すると、ビッグエディアンからリトルエディアンに変換し、ビッグエディアン環境でコンパイル&実行すると何もしない関数」が「ntohl関数そのもの」
となります(関数名が違う事に注意)

つまり
「送出時は、htonl関数を呼んで送出する」
「受信時は、受信してからntohl関数を呼ぶ」
と言う事になります。

そういう訳で、htonl関数、ntohl関数とは「ネットワークバイトオーダーとローカルバイトオーダーを変換する関数のセット」と言う事になります。

そしてこれは「htonl関数、ntohl関数を呼んでさえおけば、実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言う事を意味します。

この「実行するマシンが、リトルエディアンかビッグエディアンか気にする必要はない」と言うのが、ANo2の方が書いた
>htonlを使った方が、簡単なはずです。
の「簡単」の意味です。
    • good
    • 0
この回答へのお礼

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

お礼日時:2008/12/23 00:05

> (1)簡単にそのPCがリトルエンディアンなのか、ビッグエンディアン


>  なのか、分かる方法はありますか?
リトルエンディアン・ビッグエンディアンがどう言ったものであるか
理解しているなら、その判別プログラムも簡単に書ける事でしょう。

分からない場合は、ウェブで調べると良いです。
たぶん、すぐ見つかります。

・Wikipedia
http://ja.wikipedia.org/wiki/%E3%82%A8%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;
}
----------------------------------------------------------------------
エンディアンの判別プログラムは、こんな感じです。

この回答への補足

ご回答ありがとうございます。
判定プログラムありがとうございます。
すごく分かりやすいです。

一点質問なのですが、
>htonlを使った方が、簡単なはずです。
これは具体的にはどのような意味なのでしょうか?

補足日時:2008/12/16 07:12
    • good
    • 0

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


ということで, ビッグエンディアンと決めつけるのは危険だと思います.
    • good
    • 0
この回答へのお礼

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

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

お礼日時:2008/12/16 07:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!