2010-09-23 5 views

Répondre

13

La sortie est différente en raison de l'ordre dans lequel le préprocesseur fait les choses, ce qui est décrit dans la section 6.10.3 (et suivantes) dans la norme C99. cette phrase de 6.10.3.1/1 en particulier:

Un paramètre dans la liste de remplacement, si elle est précédée d'un jeton ou suivi d'un jeton ## prétraiter prétraiter # ou ##, est remplacé par l'argument correspondant après tout les macros qui y sont contenues ont été étendues.

Ainsi, dans la première ligne, lors de l'expansion de l'invocation h, l'argument f(1,2) est dilatée avant remplace le paramètre de ha. Le # n'intervient que plus tard lorsque l'invocation de g qui en résulte est vue lorsque la sortie de tout ce qui est resynchronisé.

Mais sur la deuxième ligne, le # est vu immédiatement et la clause "sauf précédé par ..." de la citation ci-dessus déclenche le comportement différent.

Voir aussi the relevant C-FAQ entry.

8

Après le préprocesseur se fait avec l'expansion macro, le compilateur voit ceci:

int main() 
    { 
     printf("%s\n","printf(\"yes\")"); 
     printf("%s\n","f(1,2)"); 
    } 

Ceci est une technique courante à la couche dans une indirection « extra » pour contrôler quand vous obtenez mise en chaîne et quand vous obtenez réelle évaluation macro. Fondamentalement, l'évaluation de la macro se produit à partir de l'extérieur de l'extérieur, et non l'inverse. Le wikipedia page indique que «les paramètres ne sont pas analysés pour le remplacement de macro d'abord» qui je crois se rapporte à la même chose.

Questions connexes