Programmation C: préprocesseur, macros en tant que jetons

J’essaie de faire quelque chose qui est conceptuellement similaire à ceci, mais je n’arrive pas à le faire fonctionner (erreur montrée à la fin) des idées?

#include  int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR(prefix) prefix##_def_##SUFFIX printf( "%d\n" , VAR(abc) ); return 0; } // untitled:8: error: 'abc_def_SUFFIX' undeclared (first use in this function) 

Vous avez juste besoin d’un indirection supplémentaire:

 #include  int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR3(prefix, suffix) prefix##_def_##suffix #define VAR2(prefix, suffix) VAR3(prefix, suffix) #define VAR(prefix) VAR2(prefix, SUFFIX) printf( "%d\n" , VAR(abc) ); return 0; } 

Même si cela semble redondant, ce n’est pas le cas.

L’idiome habituel pour utiliser correctement les opérateurs de prétraitement ssortingngizing ( # ) ou collage de jetons ( ## ) consiste à utiliser un deuxième niveau d’indirection. ( Quelles sont les applications de l’opérateur de préprocesseur ## et des pièges à prendre en compte? ).

 #define STRINGIFY2( x) #x #define STRINGIFY(x) STRINGIFY2(x) #define PASTE2( a, b) a##b #define PASTE( a, b) PASTE2( a, b) 

Ensuite:

 int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR(prefix) PASTE( prefix, PASTE( _def_, SUFFIX)) printf( "%d\n" , VAR(abc) ); return 0; } 

Devrait vous donner les résultats que vous recherchez.

En gros, le traitement des opérateurs # et ## a lieu avant le remplacement de la macro. Ensuite, un autre cycle de remplacement de macro se produit. Donc, si vous voulez que les macros soient utilisées avec ces opérations, vous devez utiliser un 1er niveau qui effectue simplement le remplacement – sinon, l’enchaînement ou le collage se produit en premier, et les macros ne sont plus des macros. ssortingngizing / collage produit.

Pour le dire plus directement – le premier niveau de macro permet de remplacer les parameters de la macro, puis le deuxième niveau de remplacement de la macro effectue l’opération ssortingngify / token-colling.

Cela fonctionne avec des niveaux suffisants d’indirection. Bien qu’une autre réponse soit tout à fait adéquate, je souhaite proposer cette partie de code sous forme de démo:

 #define SUFFIX ghi #define VAR1(prefix) prefix##_def_##SUFFIX VAR1(abc) #define VAR2_(prefix, sfx) prefix##_def_##sfx #define VAR2(prefix) VAR2_(prefix,SUFFIX) VAR2(abc) #define VAR3_(prefix, sfx) prefix##_def_##sfx #define VAR3x(prefix,sfx) VAR3_(prefix,sfx) #define VAR3(prefix) VAR3x(prefix,SUFFIX) VAR3(abc) 

Save this est un fichier texte, xc, et ne le prétraitement.

 gcc -E xc 

Observe et médite. Je ne comprends pas tout à fait moi-même. Passez juste deux heures à essayer d’obtenir une macro utilisant ssortingngify pour fonctionner. Il est intéressant de voir que la double indirection est parfois nécessaire.