プリプロセッサの条件式と通常の条件式は結果が異なる?
c および c++ のプリプロセッサ #if
の条件式と、いわゆる「本文」中の条件式は同じ結果を得るものだと思っていましたが、違うことがあるようです。
#include <stdio.h>
#define PHYSICAL_ROM_TOP (-262144) /* 0xFFFC0000 を符号付きで表記 */
int main() {
printf("%d\n", PHYSICAL_ROM_TOP==0xFFFC0000);
#if PHYSICAL_ROM_TOP==0xFFFC0000
printf("same\n");
#else
printf("different\n");
#endif
return 0;
}
Visual C++ 2005 での結果 cl -Ox -FAsc foo.c
で 1 different
gcc-4.9.4@hppa2.0w-hp-hpux11.11 での結果 gcc -O foo.c
で 1 different
野良ビルドした gcc-7.1.0@i686-pc-cygwin (32bit) での結果 1 different
某組み込み系ワンチップマイコン用のコンパイラの1 1 different
某組み込み系ワンチップマイコン用のコンパイラの2 1 same
ちゃんとコンパイル時定数式として扱ってくれているかどうかの確認のためアセンブラも出力させてみました。最適化を有効にすると全てのコンパイラで 1
に対して即値を生成しているので、コンパイル時定数式と見てくれているのは間違いないです。
言語規格書をチラ見した範囲ではこの違いについて納得できる説明を見つけることができませんでした (c++ 規格書 JIS X 3014:2003 の 16.1 や 5.19 や 18.2)
この #if
が #else
側になる説明をしていただけると幸いです。