Below are some related concepts to your question:
[Argument Prescan][2]:
> Macro arguments are completely macro-expanded ***before*** they are
> substituted into a macro body, unless they are ***stringified*** or ***pasted***
> with other tokens. After substitution, the entire macro body,
> including the substituted arguments, is scanned ***again*** for macros to be
> expanded. The result is that the arguments are scanned twice to expand
> macro calls in them.
>
[Stringification][3]
> When a macro parameter is used with a leading ‘#’, the preprocessor
> replaces it with the literal text of the actual argument, converted to
> a ***string constant***.
`#ABC => "ABC"` <---- Note the enclosing double quote, which is added by the stringification process.
[Token Pasting / Token Concatenation][4]:
> It is often useful to merge two tokens into one while expanding
> macros. This is called ***token pasting*** or ***token concatenation***. The ‘##’
> preprocessing operator performs token pasting. When a macro is
> expanded, the two tokens on either side of each ‘##’ operator are
> combined into a single token, which then replaces the ‘##’ and the two
> original tokens in the macro expansion.
So the detailed process of your scenario is like this:
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.
[2]:
[To see links please register here]
[3]:
[To see links please register here]
[4]:
[To see links please register here]