La confusion vient ici d'une règle simple.
Lors de l'évaluation d'une macro, le préprocesseur résout d'abord les macros dans les arguments transmis à la macro. Toutefois, dans un cas particulier, si un argument a la valeur #
ou est adjacent à ##
, il ne résout pas les macros dans ces arguments. Telles sont les règles.
Votre premier cas
C(A(1,2))
Le pré-processeur applique d'abord la macro C(a)
, qui est défini comme B(a)
. Il n'y a pas #
ou ##
à côté de l'argument dans la définition (aucun d'entre eux dans B(a)
du tout), ainsi le pré-processeur doit résoudre des macros dans l'argument:
A(1,2)
La définition de A(a,b)
est a##b
qui évalue en 12
.
Après les macros dans les arguments de la C(a)
macro sont évalués, la macro C devient:
C(12)
Le pré-processeur résout l'C(a)
macro qui, selon sa définition devient
B(12)
Une fois cela fait, le pré-processeur évalue à nouveau les macros dans le résultat et applique la macro B(a)
, de sorte que le résultat devient
"12"
Votre second cas
B(A(1,2))
Tout comme le premier cas, le pré-processeur applique d'abord la B(a)
macro. Mais cette fois, la définition de la macro est telle que l'argument est précédé de #
. Par conséquent, la règle spéciale s'applique et les macros à l'intérieur de l'argument sont et non évaluée.Par conséquent, le résultat devient immédiatement:
"A(1,2)"
Le préprocesseur va sur le résultat à nouveau en essayant de trouver plus des macros pour développer, mais maintenant tout est une partie de la chaîne, et les macros ne sont pas remplacées dans les chaînes. Ainsi, le résultat final est:
"A(1,2)"
Voir http://stackoverflow.com/questions/14351971/what-does-x-inside-ac-macro-mean/14352054#14352054 et http://stackoverflow.com/questions/1489932/comment-concaténer-deux fois-avec-le-c-préprocesseur-et-élargir-une-macro-comme-dans-arg – Michael