81 votes

Comment fonctionne exactement le tour double-stringize?

Au moins certains C préprocesseurs laissez vous stringize la valeur d'une macro, plutôt que son nom, en le passant à travers une seule fonction, comme la macro à un autre qui stringizes:

#define STR1(x) #x
#define STR2(x) STR1(x)
#define THE_ANSWER 42
#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */

Exemple de cas d'utilisation ici.

Cela ne fonctionne, au moins dans GCC et Clang ( -std=c99), mais je ne suis pas sûr de la façon dont il fonctionne dans C-conditions standard.

Est ce comportement garantis par C99?
Si oui, comment C99 garantie?
Si non, à quel point le comportement de passer de C-défini à GCC-défini?

76voto

Steve Jessop Points 166970

Oui, c'est garanti.

Cela fonctionne parce que des arguments pour les macros sont eux-mêmes macro-expansion, sauf lorsque la macro argument le nom apparaît dans la macro corps avec la stringifier # ou le jeton-paster ##.

6.10.3.1/1:

... Après les arguments en faveur de la l'invocation d'une fonction-comme macro ont été identifiés, argument la substitution a lieu. Un paramètre dans la liste de remplacement, à moins que précédé d'un # ou ## prétraitement jeton ou suivie par un ## prétraitement jeton (voir ci-dessous), est remplacé par l'argument correspondant après toutes les macros qui y sont contenues ont été élargis...

Donc, si vous n' STR1(THE_ANSWER) , puis vous obtenez "THE_ANSWER", parce que l'argument de STR1 est pas de la macro-expansion. Cependant, l'argument de STR2 est de la macro-expansion lorsqu'il est substitué dans la définition de STR2, ce qui lui donne de STR1 un argument de 42, avec le résultat de "42".

19voto

Chris Dodd Points 39013

Comme le note Steve, cela est garanti, et ce depuis la norme C89 - c’est la norme qui codifiait les opérateurs # et ## dans les macros et les obligeait à développer de manière récursive des macros dans des arguments avant de les substituer dans le corps si et seulement si le corps n'applique pas # ou ## à l'argument. C99 est inchangé par rapport à C89 à cet égard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X