Macro-fonction pour générer une macro avec préfixe (éviter la chaîne de caractères)

Contexte

J’ai un projet dans lequel j’ai deux produits distincts avec des noms de macro presque identiques, pour lesquels je voudrais créer une fonction semblable à une macro afin de récupérer rapidement les valeurs des macros. J’ai écrit une macro-fonction getTranslation pour prendre le texte littéral fourni à la “fonction”, qui devrait être traité comme une chaîne et un préfixe de chaîne (illustré ci-dessous).


Question

Comment puis-je effectuer cette opération en prenant les arguments fournis à la macro, en les concaténant ensemble (avec un trait de soulignement au milieu), et en traitant ce résultat comme une macro de pré-traitement au lieu d’une chaîne?


Liste de code

 /******************************************************************************* * coconut.h ******************************************************************************/ #define COCONUT (PRODUCT_COCONUT) #define COCONUT_FX_REGISTER (100) #define COCONUT_BASE_REGISTER (101) /******************************************************************************* * pineapple.h ******************************************************************************/ #define PINEAPPLE (PRODUCT_PINEAPPLE) #define PINEAPPLE_FX_REGISTER (200) #define PINEAPPLE_BASE_REGISTER (201) /******************************************************************************* * test.c. ******************************************************************************/ #include  #include "translation.h" #include "coconut.h" int main(void) { int i = getTranslation(FX_REGISTER, COCONUT); printf("Translation:%d.\n", i); return 0; } /******************************************************************************* * translation.h ******************************************************************************/ #define FX_REGISTER (0) #define BASE_REGISTER (1) #define getTranslationInternal(x, y) #y "_" #x #define getTranslation(x, y) getTranslationInternal(x, y) enum Products { PRODUCT_COCONUT = 0, PRODUCT_PINEAPPLE, PRODUCT_MAX, PRODUCT_INVALID = (-1) }; 

Avertissements du compilateur

 test.c: In function 'main': test.c:10:45: warning: initialization makes integer from pointer without a cast [-Wint-conversion] int i = getTranslation(FX_REGISTER, COCONUT); ^ translation.h:7:39: note: in definition of macro 'getTranslationInternal' #define getTranslationInternal(x, y) #y "_" #x ^ test.c:10:10: note: in expansion of macro 'getTranslation' int i = getTranslation(FX_REGISTER, COCONUT); 

Exemple de cycle

 Translation:4195812. 

 #define getTranslationInternal(x, y) y ## _ ## x 

travaillé pour moi sur clang, si vous déposez des parenthèses autour des définitions de macro.