C++ ストリームでマルチバイト型のエンディアンを保証する組み込みの方法はありますか? 特に、ストリームとの間で小さな char 配列を読み書きしたいと考えてread()
います。write()
これらが常にリトルエンディアン形式で保存されるようにする必要があります。(はい、一度に 1 バイトずつ、またはシフト & などを使用して実行できますが、それは私の質問ではありません。)
5 に答える
char 配列の場合、各文字は 1 バイトであるため、エンディアンを気にする必要はありません。整数などを一連のバイトとしてコーディングしている場合、ストリームは char 配列としてではなく、型付き配列として読み書きする必要があるため、何を扱っているかがわかります。つまり、整数をバイトにキャストするまでに、エンディアンを回復するために必要な情報を失ってしまいます。
それを保証する方法はありません。とにかく、コンパイラではなく、アーキテクチャによって決定されると確信しています。ただし、エンディアンを確認する方法はあります。
あなたの特定のケースでは、私の知る限り、C++ のすべての深刻な実装はchar
s を 1 バイトとして格納するため、実際には心配はありません。
シフトなしでこれを行う方法はないため、アーキテクチャでは、作業中にメモリ内で特定の順序でそれらを保持する必要があります。最も簡単な回避策は、バイトオーダーマークを使用することです。これが受け入れられない場合は、シフトを使用する必要があります。
そして、仮定が正しいことを確認するには、次のように言うことができます
static_assert(sizeof(char) == 1, "Chars are not one byte!!!!????");
chars 配列の場合、「他の人が言ったこと」。
より複雑なデータ型については、独自に作成するのではなく、既存のシリアライゼーション プロジェクトを調べてください。これを書いている時点では、Google の protobuf は悪い選択ではないようです。
この関数は、システムのエンディアンを簡単にチェックできます。
void print_endianness() {
union {
unsigned int i;
char c[4];
} un;
un.i = 0x12345678;
if (un.c[0] == 0x78 && un.c[3] == 0x12)
printf("little-endian\n");
else if (un.c[0] == 0x12 && un.c[3] == 0x78)
printf("big-endian\n");
else
printf("unknown\n");
}