Échapper à un symbole # dans une macro #define?

Sans entrer dans les détails sanglants, je souhaite utiliser une macro #define qui s’étendra à #include mais le signe ‘#’ déroute le préprocesseur (car il pense que je veux citer un argument.)

Par exemple, je veux faire quelque chose comme ceci:

 #define MACRO(name) #include "name##foo" 

Et utilisez-le ainsi:

 MACRO(Test) 

Ce qui va s’étendre à:

 #include "Testfoo" 

Le signe humble # est à l’origine du blocage du préprocesseur. MinGW me donne l’erreur suivante:

'#' is not followed by a macro parameter

Je suppose que je dois échapper au signe #, mais je ne le fais pas si cela est possible.

Oui, les macros sont vraiment diaboliques …

    Autant que je me souvienne, vous ne pouvez pas utiliser une autre directive de préprocesseur dans define.

    Il est possible d’insérer un jeton de hachage dans le stream de jetons prétraité. Vous pouvez le faire comme suit:

     #define MACRO(hash, name) hash include name MACRO(#,"hello") 

    —Expand à:

     # include "hello" 

    Cependant , la norme exclut explicitement toute parsing ultérieure de cette ligne pour l’existence de directives de prétraitement [cpp.rescan]:

    La séquence de jetons de pré-traitement complètement remplacée par macro résultante n’est pas traitée comme une directive de pré-traitement, même si elle en ressemble à une.

    Le problème n’est pas d’obtenir un symbole # dans la sortie de votre préprocesseur.

    Apparemment, vous voulez que le préprocesseur répare votre fichier, pour traiter les directives #include récemment créées dans le cadre du développement de macros. Ça ne marche pas comme ça. Si une ligne commence par #, il s’agit d’une instruction pour le préprocesseur et interprétée. Si une ligne ne commence pas par #, elle est uniquement sujette à la transformation du préprocesseur, notamment la substitution de macros. Ceci est un test une fois par ligne.

     MACRO(Test) 

    ne commence pas par #. Par conséquent, il n’est pas interprété comme une directive de préprocesseur; au lieu de cela, il est soumis aux règles de remplacement des macros.

    En effet, le # a une signification particulière lorsqu’il est utilisé dans une macro.

     # means quote the following token (which should be a macro parameter name) ## means concatenate the preceding and following tokens. 

    Dans votre cas, le # n’est pas suivi d’un jeton approprié. Donc, dans votre situation, nous devons passer par un niveau d’indirection:

     #define QUOTE(name) #name #define TEST(name) QUOTE(name ## foo) #include TEST(scot) 

    Tu ne peux pas faire ça. Les directives du préprocesseur sont reconnues avant le développement des macros; si la macro se développe en quelque chose qui ressemble à une directive de préprocesseur, cette directive ne sera pas reconnue. Le mieux que vous puissiez faire est de créer une macro pour le nom du fichier:

     #define MACRO(name) "name##foo" ... #include MACRO(Test) 

    Cela pourrait fonctionner (cela fonctionne pour les macros #define régulières sans parameters, mais je ne l’ai pas testé avec des macros avec parameters).

     #define MACRO(name)  #include MACRO(Test) 
     #define HASH_SIGN # BOOST_PP_CAT(HASH_SIGN, include) 
     #define PARAM_NAME Param #define GETNAME_(a) #a #define GETNAME(a) GETNAME_(a) int Param; printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);