Comment imprimer une livre / hachage via le préprocesseur C?

J’ai besoin d’aide pour:

une étiquette de macro de préprocesseur (x) doit générer “#x”, par exemple,

#define label(x) ... 

si j’appelle label (aname), le résultat sera “#aname” (sans guillemets)

Je sais que les essais suivants ont été des erreurs.

 #define label(x) #x // leads to "x" #define label(x) \#x // is \"x" #define label(x) "#x" // is "#x" (but not the content of x") "#otto" 

Il peut exister une sorte de # échappé (livre), mais je ne sais pas, comment échapper …

Edit : Je lance “gcc -E test -o test.html” pour obtenir le résultat. Le problème est le suivant: comment imprimer un signe dièse (#) avec un makro utilisant uniquement les fonctionnalités du préprocesseur?

La réponse est:

 #define hash # #define f(x) x #define label(a) f(hash)a 

puis

 label(foobar) 

crée

 #foobar 

Je l’ai trouvé avec l’aide de tous , mais surtout en hiver. Merci beaucoup!

(Utiliser gcc 4.3.3)

Je ne pense pas que vous puissiez le faire, ce qui n’est pas totalement déraisonnable car la sortie du préprocesseur C ne devrait pas produire un ‘#’ non indiqué car cela indiquerait une directive de pré-processeur, et vous ne pouvez pas générer des directives de pré-processeur à la volée comme cette.

En d’autres termes, le préprocesseur C est un préprocesseur pour C (et C ++) et non un outil complètement général.

Utilisez un autre processeur de macros ( m4 est la recommandation standard sur les systèmes de type Unix) ou procédez différemment.

Par exemple, remplacez la macro:

 #define label(x) !@!x 

Puis post-traiter la sortie en remplaçant “! @!” avec ‘#’.

(Le programme imake utilise une cascade similaire; le préprocesseur C effectue la majeure partie du travail, mais sa sortie ne conserve pas les sauts de ligne nécessaires à ‘make’, aussi ‘imake’ utilise la notation ‘@@ \’ ou à peu près pour indiquer où les sauts de ligne doivent être insérés une fois que le préprocesseur C a fait le pire.)

Vous pouvez faire quelque chose comme ça:

 #define f(x) x #define label(a) f(#)a 

J’ai testé cela en l’exécutant directement via cpp (le préprocesseur C) au lieu de gcc . Exemple:

 cpp test > test.html 

Utilisation du cpp faisant partie de gcc version 4.0.1.

Le seul problème que j’ai remarqué est que j’obtiens une sortie supplémentaire indésirable, à savoir les 4 premières lignes du fichier sont les suivantes:

 # 1 "test" # 1 "" # 1 "" # 1 "test" 

Les littéraux de chaîne en C seront concaténés, vous pourrez donc le faire

 #define label(x) "#" #x 

Je ne pense pas que ce soit possible sans concaténation de chaînes (c’est-à-dire sans appeler le compilateur C comme vous le souhaitez):

Vous pouvez faire des choses fantaisistes avec des niveaux supplémentaires d’indirection et j’ai même demandé au préprocesseur de générer la sortie souhaitée via

 #define hash # #define quote(x) #x #define in_between(c, d) quote(c ## d) #define join(c, d) in_between(c, d) #define label(x) join(hash, x) label(foo) 

Le problème est qu’il générera également un message d’erreur lorsque in_between() développe en #foo , ce qui n’est pas un jeton de préprocesseur valide. Je ne vois aucun moyen de contourner cela.

Mon conseil serait de choisir le bon outil pour le travail: passez à un autre langage de macro tel que m4 ou même ML / I si vous vous sentez aventureux ou utilisez un langage de script tel que PHP ou Perl. GPP semble bien aussi et pourrait être un meilleur ajustement.

Essayer:

 #define label(x) "#"x