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

main.cpp

// 目標
//   コンパイル時定数 exp が、
//     0 のとき     : コンパイルエラー
//     0 以外のとき : 実行時コスト0 (= コンパイル後のコードに現れない)
//   ような、StaticAssert(exp) を作る。
//   [追加条件]
//   exp が コンパイル時に決まらない変数の場合もコンパイルエラーとなること。

// 0 が現れたときにコンパイルエラーとなるような文を考える。

// C/C++ では、配列の宣言において、配列の大きさを指定する場合、
// その大きさは 0より大きくなくてはならないと規定されている。

// そこで、exp が 0 のとき、StaticAssert(exp) が
// 大きさ 0 の配列宣言に置き換わるように定義してみる。

#define    StaticAssert(exp)   {int dummyArray[(exp) ? 1 : 0] ;}

int main(void){
    StaticAssert(1) ;   // コンパイルを通ること
    StaticAssert(2) ;   // コンパイルを通ること

    StaticAssert(0) ;   // コンパイルエラーとなること

    int i = 1 ;
    StaticAssert(i) ;   // コンパイルエラーとなること

    return 0 ;
}

// 確かに期待した行で
//   「サイズが 0 の配列を割当てまたは宣言しようとしました。」
// というエラーが発生し、かつ、
// コンパイルを通った部分については、コンパイル後のコードに現れないので目標達成。
// なんだけど、
// (1) コンパイルが通っても「'dummyArray' : ローカル変数は 1 度も使われません。」という
//     warning が出てカッコワルイ。この warning を消せないか。
// (2) エラーメッセージがもうちょっと判りやすくなるように工夫できないか。
//    (こっちはコンパイラ依存なので全ての環境で同じように動作させることは無理っぽいが……。)