このトピックでは、SOで多くの質問を述べましたが、これまでのところ解決策が見つかりませんでした。 1つの自然な解決法がここに言及された:Determining endianness at compile time。
しかし、コメントに記載されている関連する問題&は同じ答えです。C++を使用してコンパイル時にプログラムでエンディアンを見つける11
いくつかの変更を加えて、g ++ & clang ++(-std=c++11
)で同様の解決策を警告なしにコンパイルできます。
static_assert(sizeof(char) == 1, "sizeof(char) != 1");
union U1
{
int i;
char c[sizeof(int)];
};
union U2
{
char c[sizeof(int)];
int i;
};
constexpr U1 u1 = {1};
constexpr U2 u2 = {{1}};
constexpr bool IsLittleEndian()
{
return u1.i == u2.c[0]; // ignore different type comparison
}
static_assert(IsLittleEndian(), "The machine is BIG endian");
Demo。
これは、エンディアンを決定する決定的な方法と見なすことができますか?それとも、タイプ・パンニングなどがありませんか?
'uint8_t(u2.i)'はどちらのエンディアンでも同じ値を生成しませんか?キャストは、最初のバイトを選択するだけでなく、値を保持する必要があります。 –
4バイトの整数には、24の可能なバイト順序があります。実際のコンピュータでは少なくとも3つ以上が使用されています。また、[['' un'] 'signed''' char'に与えられた厳密なエイリアシング規則の例外が 'uint8_t'に適用されることは完全にはっきりしていません。 –
@BoPersson、私は "異なるサイズのタイプの比較"に関するコンパイラの警告を避けたかったのです(私はQ!で主張しようとしています)。ここからは、最小の型で1が表現されますが、型キャストでは許容されることがわかりました。それとも私はあなたの心配を誤解しましたか?私は少しコードを変更します。 – iammilind