マシンのエンディアンを判断するためにマクロを検索しましたが、これに対応する標準のプロプロセッサ マクロは見つかりませんでしたが、多くのソリューションが実行時にそれを実行しています。実行時にエンディアンを検出する必要があるのはなぜですか?
私がそのようなことをしたら:
#ifdef LITTLE_ENDIAN
inline int swap(int& x) {
// do swap anyhow
return swapped;
}
#elif BIG_ENDIAN
inline int& swap(int& x) { return x; }
#else
#error "some blabla"
#endif
int main() {
int x = 0x1234;
int y = swap(x);
return 0;
}
コンパイラは 1 つの関数のみを生成します。
しかし、私がそれを好きなら(predef.endianを参照):
enum {
ENDIAN_UNKNOWN,
ENDIAN_BIG,
ENDIAN_LITTLE,
ENDIAN_BIG_WORD, /* Middle-endian, Honeywell 316 style */
ENDIAN_LITTLE_WORD /* Middle-endian, PDP-11 style */
};
int endianness(void)
{
uint8_t buffer[4];
buffer[0] = 0x00;
buffer[1] = 0x01;
buffer[2] = 0x02;
buffer[3] = 0x03;
switch (*((uint32_t *)buffer)) {
case 0x00010203: return ENDIAN_BIG;
case 0x03020100: return ENDIAN_LITTLE;
case 0x02030001: return ENDIAN_BIG_WORD;
case 0x01000302: return ENDIAN_LITTLE_WORD;
default: return ENDIAN_UNKNOWN;
}
int swap(int& x) {
switch(endianess()) {
case ENDIAN_BIG:
return x;
break;
case LITTLE_ENDIAN:
// do swap
return swapped;
break;
default:
// error blabla
}
// do swap anyhow
}
コンパイラは検出用のコードを生成します。
わからない、なぜ私はこれをしなければならないのですか?
リトル エンディアン マシン用にコンパイルされたコードがある場合、コード全体がリトル エンディアン用に生成され、そのようなコードをビッグ エンディアン マシン (arm wiki:bi-endian のようなバイ エンディアン マシン) で実行しようとすると) コード全体がリトルエンディアン マシン用にコンパイルされます。したがって、int などの他のすべての宣言も le です。
// compiled on little endian
uint32_t 0x1234; // 0x1234 constant literal
// should result 34120000 on BE