La norme C11 dit (et les autres versions de C, et C++, dire de même):
Un prétraitement de la directive de la forme # define identifier replacement-list new-line
définit un objet-comme macro qui provoque par la suite, chaque instance du nom de la macro à être remplacé par la liste de remplacement de prétraitement des jetons qui constituent le reste de la directive. La liste de remplacement est alors remplacé pour plus de noms de macro comme spécifié ci-dessous.
Toutefois, il a également dit dans une autre partie (grâce à rici pour le signaler).
Le prétraitement des jetons à l'intérieur d'un prétraitement de la directive ne sont pas soumis expansion de macro, sauf indication contraire.
Si une instance suivante du nom de la macro qui se trouve à l'intérieur d'un autre #define
directive est en fait pas remplacé.
Votre ligne, #define FOO NUM
définit que lorsque le jeton FOO
est constaté plus tard (à l'extérieur de l'autre #define
directive!), il sera remplacé par le jeton NUM
.
Après un jeton est remplacé, en analysant de nouveau se produit, et si l' NUM
est elle-même une macro, alors NUM
est remplacé à ce point. (Et si ce NUM
développe contient des macros , puis qui devient élargi , et ainsi de suite).
Si votre séquence d'étapes est:
-
NUM
défini comme 10
-
FOO
défini comme NUM
-
NUM
undefined et ré-défini comme 20
-
FOO
s'étend à d' NUM
- (rebalayage)
NUM
s'étend à d' 20
Ce comportement peut être vu dans un autre commune de préprocesseur astuce, pour tourner la définition de la valeur d'une macro dans une chaîne de caractères:
#define STR(X) #X
#define STR_MACRO(X) STR(X)
#define NUM 10
puts( STR_MACRO(NUM) ); // output: 10
Si nous avions écrit puts( STR(NUM) )
le résultat NUM
.
La sortie de l' 10
est possible parce que, comme avant, le deuxième #define
ici ne fait pas l'étendre STR
. Donc, la séquence d'étapes dans le présent code est:
-
STR(X)
défini comme #X
-
STR_MACRO(X)
défini comme STR(X)
-
NUM
défini comme 10
-
STR_MACRO
et NUM
sont à la fois étendues; le résultat est puts( STR(10) );
- (Rescan résultat de la dernière extension)
STR(10)
est élargi à d' "10"
- (Rescan résultat de la dernière extension) Aucune possibilité d'expansion.