コンパイル時にネイティブエンディアンを判定するには?
実行時にネイティブエンディアンがリトルエンディアンか否かは、例えば以下のように判定できます。
#include <iostream>
const int bom = 1;
bool is_little_endian() {
return *reinterpret_cast<const char *>(&bom) == 1;
}
int main()
{
const bool b = is_little_endian();
std::cout << b << '\n';
}
C++11で定数式の機能(constexpr)が追加されたので、constをconstexprに変えればコンパイル時に判定できるのではないかと考えたのですが、reinterpret_castは定数式の中では使えないようで、コンパイルエラーになります。
#include <iostream>
constexpr int bom = 1;
constexpr bool is_little_endian() {
return *reinterpret_cast<const char *>(&bom) == 1;
}
int main()
{
constexpr bool b = is_little_endian();
std::cout << b << '\n';
}
;
# clang++ -Wall -std=c++11 test_endian.cpp
test_endian.cpp:4:16: error: constexpr function never produces a constant
expression [-Winvalid-constexpr]
constexpr bool is_little_endian() {
^
test_endian.cpp:5:10: note: reinterpret_cast is not allowed in a constant
expression
return *reinterpret_cast<const char *>(&bom) == 1;
^
1 error generated.
コンパイル時にはネイティブエンディアンは決まっていると思うのでコンパイル時に判定したいのですが、Boostライブラリのようにコンパイラー独自のマクロで判定する方法以外で、何か方法はありますか?
※リトルエンディアンか否かだけではなく、リトルエンディアン/ビッグエンディアン/その他に分類できればベストです。
■追記
用途としては、外部データと内部データを変換する関数/クラスを作る場合に、外部データのエンディアンとネイティブエンディアンの関係で実装を最適化する、ということを想定しています。