C 宏函数生成带有前缀的宏(避免字符串化) 出身背景

C 宏函数生成带有前缀的宏(避免字符串化) 出身背景,c,gcc,c-preprocessor,C,Gcc,C Preprocessor,我有一个项目,其中我有两个具有几乎相同宏名称的独立产品,我想为其创建一个类似宏的函数,以快速检索宏的值。我编写了一个getTranslation宏函数来获取提供给“函数”的文本,该函数应被视为字符串和字符串前缀(如下所示) 问题 如何完成这个操作:获取提供给宏的参数,将它们连接在一起(中间有一个下划线),并将结果作为预处理器宏而不是字符串处理 代码清单 样本运行 如果你在宏定义周围放上括号,我在clang上工作过。define getTranslationInternal(x,y)y#u#

我有一个项目,其中我有两个具有几乎相同宏名称的独立产品,我想为其创建一个类似宏的函数,以快速检索宏的值。我编写了一个
getTranslation
宏函数来获取提供给“函数”的文本,该函数应被视为字符串和字符串前缀(如下所示)


问题 如何完成这个操作:获取提供给宏的参数,将它们连接在一起(中间有一个下划线),并将结果作为预处理器宏而不是字符串处理


代码清单
样本运行
如果你在宏定义周围放上括号,我在clang上工作过。

define getTranslationInternal(x,y)y#u#u#u#x?@rici有几个错误:
错误:粘贴“”(产品)和“#”没有给出有效的预处理令牌,
粘贴“#”和“(”未给出有效的预处理令牌
,并且在
之前应给出“、”或“;”。如果您试图使用宏
(y#######x
获取
椰子#FX
寄存器,则
椰子#FX#寄存器
(100)
,你为什么期望
4195812
?@PSkocik我不期望
4195812
,但我得到了它,很可能是因为我的代码中有一个bug。@DevNull:对,你需要去掉
产品
周围的括号,才能让令牌连接起作用。(或者,就此而言,字符串化。)这样做了,但是,我不得不完全删除
getTranslationInternal
,只需
#定义getTranslation(x,y)y######x
。不再使用字符串化效果:)。谢谢
/*******************************************************************************
 * 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 <stdio.h>
#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)
};
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);
Translation:4195812.
#define getTranslationInternal(x, y)    y ## _ ## x