endian.hpp on NetBSD
せっかくSourceForge.jpのコンパイルファームにNetBSD(x86)マシンがあるので、Hamigakiライブラリのビルドを試してみました。
で、Hamigaki.Charsetのテストでエンディアンが逆に判定されるという現象に遭遇しました。
問題の箇所はこうです。
template<> struct wide_code_page_tarits<4> { static const char* name() { #if defined(BOOST_LITTLE_ENDIAN) return "UTF-32LE"; #else return "UTF-32BE"; #endif } };
stringsしてみると、ビッグエンディアンと判定されているのが分かります。
-bash-2.05b$ strings ~/src/hamigaki/bin.v2/libs/charset/test/code_page_test.test/gcc-4.1.2/debug/code_page_test.o | grep UTF UTF-32BE UTF-7 UTF-8
確認のため、次のコードを試してみました。
#include <boost/detail/endian.hpp> #include <iostream> int main() { #if defined(BOOST_LITTLE_ENDIAN) std::cout << "BOOST_LITTLE_ENDIAN" << std::endl;; #endif #if defined(BOOST_BIG_ENDIAN) std::cout << "BOOST_BIG_ENDIAN" << std::endl;; #endif std::cout << BOOST_BYTE_ORDER << std::endl;; }
結果は、
BOOST_LITTLE_ENDIAN 1234
となって問題ありません。
となると、どこかのヘッダが悪さをしていることになります。
そこでプリプロセスの結果を眺めて原因を突き止めました。
問題は<sys/endian.h>内部で、「_LITTLE_ENDIAN」、「_BIG_ENDIAN」、「_PDP_ENDIAN」の3つが定義されていることです。
<boost/detail/endian.hpp>では、
#elif defined(_BIG_ENDIAN) # define BOOST_BIG_ENDIAN # define BOOST_BYTE_ORDER 4321 #elif defined(_LITTLE_ENDIAN) # define BOOST_LITTLE_ENDIAN # define BOOST_BYTE_ORDER 1234
となっているため、<sys/endian.h>が先にインクルードされた場合、ビッグエンディアンと判定されてしまいます。
_BIG_ENDIANや_LITTLE_ENDIANはHP-UXで使われるらしいので、
#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) # define BOOST_BIG_ENDIAN # define BOOST_BYTE_ORDER 4321 #elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) # define BOOST_LITTLE_ENDIAN # define BOOST_BYTE_ORDER 1234
とでもしておけばよいと思います。
バグ報告もしておきます。