それはC++std16.3.4で言います:
[マクロ呼び出しの置換からの]結果の前処理トークンシーケンスは、ソースファイルの後続のすべての前処理トークンとともに再スキャンされ、さらにマクロ名を置換します。
置換リストのこのスキャン中に置換されるマクロの名前が見つかった場合(ソースファイルの残りの前処理トークンは含まれません)、置換されません。
さらに、ネストされた置換で置換されるマクロの名前が検出された場合、そのマクロは置換されません。
これらの置換されていないマクロ名前処理トークンは、そのマクロ名前処理トークンが置換されていたコンテキストで後で(再)検査された場合でも、それ以上の置換には使用できなくなります。
ネストされたマクロ置換とは正確には何ですか?
具体的に次のことを考慮してください。
#define f(x) 1 x
#define g(x) 2 x
g(f)(g)(3)
私は次のことを期待していました:
g(f)(g)(3) <-- first replacement of g, ok
2 f(g)(3) <-- nested replacement of f, ok
2 1 g(3) <-- second nested replacement of g, don't replace, stop
ただし、gccは予期せずgの2番目の置換を進め、次のように生成します。
2 1 2 3
何か案は?
アップデート:
多くの調査の後、より簡単な例でこの問題を解決しましょう。
#define A(x) B
#define B(x) A(x)
A(i)(j)
これは次のように拡張されます。
A(i)(j)
B(j)
A(j)
この規格ではA(j)
、拡張する必要があるかどうかは指定されてB
いません。A(j)
委員会は、現実世界のプログラムがこの振る舞いに依存A(j)
することは期待されていないため、このままにすることを決定しましたB
。