Notice : 内容無保証。禁無断転載。リンク不自由。

main.cpp

#include <stdio.h>
#include <assert.h>

static const int _ONE_ = 1 ;

// assert() による前提条件のチェック付き isLittleEndianCPU()

#define isLittleEndianCPU() (\
    assert(sizeof(char) < sizeof(int)),\
    *((char*)(&_ONE_)) != 0\
)

// ちなみに、VC++ 6.0 でコンパイル後のコードを調べてみると、
// 前提条件が成り立つなら、チェックにかかる実行時コストは 0 であった。
// // ↑
// // #define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
// // と定義されてるので、もともと exp が 0 のときしか
// // _assert() が呼ばれないようになってるんだけど、
// // コンパイル時に exp が非0定数だと判定できた場合には、
// // 最適化により _assert() の呼び出しコード自体が削除される。
// // 最後に残る (void)((exp)) も、何ら効果が無い式であり、
// // コンパイル後の コードには現れない。
//
// つまり、コンパイル時定数をチェックするための assert() では、
// 実行効率には何のペナルティも生じない。(VC++ 6.0)
//
// もちろん前提条件が成り立たない/実行時にしか判定できない場合は、
// _assert() 呼び出しのためのコスト (= コード量増大) がかかる

int main(void){
    if (isLittleEndianCPU()){
        printf("Little Endian.\n") ;
    }else{
        printf("Big Endian.\n") ;
    }

    return 0 ;
}

// これはこれでうまく動くのだが……
//
// 問題点 :
//   sizeof(char) < sizeof(int) はコンパイル時に決まる定数にも関わらず、
//   実行時にしかチェックできない。
//   つまり、テスト時の網羅度が低いと発見が遅れる可能性がある。
//   前提条件が成り立たない場合、コンパイル時にエラーとして検出できないか?
//
// 目標
//   コンパイル時定数 exp が、
//     0 のとき     : コンパイルエラー
//     0 以外のとき : 実行時コスト0 (= コンパイル後のコードに現れない)
//   ような、StaticAssert(exp) を作る。
//   [追加条件]
//   exp が コンパイル時に決まらない変数の場合もコンパイルエラーとなること。