13

コンパイル時にエンディアンをチェックする方法をいくつか検索した後、次の解決策を思いつきました。

static const int a{1};

constexpr bool is_big_endian()
{
    return *((char*)&(a)) == 1;
}

GCC は、constexpr が必要な一部のコンテキストでのみこのコードを受け入れます。

int b[is_big_endian() ? 12 : 25]; //works
std::array<int, testendian() ? 12 : 25> c;  //fails

2 番目のケースでは、GCC は次のように述べてerror: accessing value of ‘a’ through a ‘char’ glvalue in a constant expressionいます。そのようなことを禁止する規格は何も見つかりませんでした。多分誰かがGCCが正しい場合を明確にすることができますか?

4

3 に答える 3

10

これは、Clang 3.1 ToT から取得したものです。

エラー: constexpr 関数は定数式を生成しません

§5.19 [expr.const]

p1 特定のコンテキストでは、この節で詳述されている追加の要件を満たす式が必要です。他のコンテキストは、式がこれらの要件を満たすかどうかに応じて異なるセマンティクスを持ちます。これらの要件を満たす式は、定数式と呼ばれます。

p2 conditional-expressionは、潜在的に評価される部分式として次のいずれかを含まない限り、コア定数式です。

  • [...]
  • ( 5.2.10 reinterpret_cast);

その(char*)&(a)ためreinterpret_cast、関数は決して有効なconstexpr関数ではありません。

于 2012-02-05T20:32:33.427 に答える
2

Boost.Detail.Endianを調べる必要があります

これは、複数のアーキテクチャのエンディアンへのマッピングです (マクロ BOOST_BIG_ENDIAN、BOOST_LITTLE_ENDIAN、および BOOST_PDP_ENDIAN を介して)。私の知る限り、このようなリスト以外に、コンパイル時にエンディアンを決定する実際の方法はありません。

Boost.Detail.Endian を使用する実装例については、Boost への提出のために審査を受けることを望んでいるライブラリを見ることができます: https://bitbucket.org/davidstone/endian/ (関連ファイルは ですがbyte_order.hppunsigned.hpp必要です私の実装を使用したい場合も同様です)。

于 2012-04-03T04:10:03.130 に答える
0

N3620 - Network Byte Order Conversion が実装されている場合、constexprntohを使用してエンディアンをチェックできますが、ミドル エンディアンのようなまれなアーキテクチャがあり、それらすべてをサポートすることはできないことに注意してください。

于 2013-11-01T22:20:50.970 に答える