このコードが C と C++ の両方で有効であることはわかっています。
#define FOO 0
#define FOO 0
ISO/IEC 14882:2011
16.3 マクロ置換 [cpp.replace]
2 現在オブジェクトのようなマクロとして定義されている識別子は、2 番目の定義がオブジェクトのようなマクロ定義であり、2 つの置換リストが同一であるという条件で、別の #define 前処理ディレクティブによって再定義できます。そうでない場合、プログラムの形式が正しくありません。同様に、関数のようなマクロとして現在定義されている識別子は、別の #define 前処理ディレクティブによって再定義できます。ただし、2 番目の定義が、パラメーターの数とスペルが同じ関数のようなマクロ定義であり、2 つの置換リストが同一である場合に限ります。そうでない場合、プログラムの形式が正しくありません。
しかし、このコードはどうですか?
#define FOO 0
#define FOO FOO
置換リストは、前処理の開始時に同一ではありません (最初の置換が発生した場合のみ)。