プリプロセッサの不思議

わかってる人には不思議でも何でもないのだが。


/* マジックナンバーを書きたくないのでenumを使う */
enum {
VERSION_INVALID,
VERSION_1,
VERSION_2,
};

/* 現在はバージョン2 */
#define CURRENT_VERSION VERSION_2

/* バージョン番号表示 */
void print_version(void)
#if CURRENT_VERSION == VERSION_2
{ printf("version 2\n"); }
#elif CURRENT_VERSION == VERSION_1
{ printf("version 1\n"); }
#else
{ printf("unknown version\n"); }
#endif

print_versionの出力結果は"version 2"となるが、間違っている。
当たり前なのだが、プリプロセッサenumを解釈しないので、VERSION_???は未定義シンボルとなる。だから未定義シンボル同士、「0 == 0」という評価が行われるという結果に。
でもってswitch〜caseで使ったりしても、コンパイル時には未定義ではないのでなかなか気付かない。