2016-10-11 3 views
0

J'essaie de rendre une section de code réutilisable. Mon commentaire extrait ne fait pas en dessous de ce que je veux à:Substitution de macros dans les macros en C

#define NAME ABC 
#define LOG_SIZE NAME##_LEN 

Je voudrais LOG_SIZE résoudre à ABC_LEN. J'ai essayé de jouer avec les #, mais je n'ai pas réussi à faire fonctionner ça. LOG_SIZE est utilisé dans le code, donc je ne veux pas changer la macro:

#define LOG_SIZE(name) name##_LEN

Est-il possible de le faire?

Répondre

3

Le problème est que les arguments de macro ne sont pas automatiquement développés s'ils sont stringifiés ou concaténés à un autre jeton.

C99 6.10.3.1/1:

Après les arguments en faveur de l'invocation d'une macro fonction semblable ont été identifiés, la substitution des arguments a lieu. Un paramètre dans la liste de remplacement, sauf s'il est précédé d'un jeton de prétraitement # ou ## ou suivi d'un jeton de prétraitement ## (voir ci-dessous), est remplacé par l'argument correspondant après que toutes les macros contenues aient été développées. Avant d'être substitués, les jetons de prétraitement de chaque argument sont complètement remplacés par des macros comme s'ils formaient le reste du fichier de prétraitement; aucun autre jeton de prétraitement n'est disponible.

Vous pouvez contourner ce problème en ajoutant une autre macro entre celui qui passe NAME et celui qui concatène avec _LEN.

#define NAME ABC 
#define AFTERX(x) x##_LEN 
#define XAFTERX(x) AFTERX(x) 
#define LOG_SIZE XAFTERX(NAME) 

LOG_SIZE 
//evaluates to ABC_LEN 

Le manuel gcc va dans plus de détails si vous êtes curieux, dans Section 3.10.6: Argument Prescan