以下は、あなたの質問に関連するいくつかの概念です。
引数プレスキャン:
マクロ引数は
、他のトークンで文字列化または貼り付けされていない限り、マクロ本体に置き換えられる前に完全にマクロ展開されます。置換後、置換された引数を含むマクロ本体全体が再度スキャンされ、展開されるマクロが検出されます。その結果、引数が2回スキャンされ、マクロ呼び出しが展開されます。
文字列化
マクロパラメータが先頭の「#」とともに使用される場合、プリプロセッサはそれを文字列定数に変換された実際の引数のリテラルテキストに置き換えます。
#ABC => "ABC"
<----文字列化プロセスによって追加される、囲んでいる二重引用符に注意してください。
トークンの貼り付け/トークンの連結:
マクロを展開するときに、2つのトークンを1つにマージすると便利なことがよくあります。これは、トークンの貼り付けまたはトークンの連結と呼ばれます。'##'前処理演算子は、トークンの貼り付けを実行します。マクロが展開されると、各「##」演算子の両側にある2つのトークンが1つのトークンに結合され、マクロ展開の「##」と2つの元のトークンが置き換えられます。
したがって、シナリオの詳細なプロセスは次のようになります。
h(f(1,2))
-> h(12) // f(1,2) pre-expanded since there's no # or ## in macro h
-> g(12) // h expanded to g
"12" // g expanded as Stringification
g(f(1,2))
-> "f(1,2)" //f(1,2) is literally strigified because of the `#` in macro g. f(1,2) is NOT expanded at all.