C中的条件#define

时间:2018-07-07 14:33:18

标签: c macros

我想用用参数控制的C语言编写条件定义。

类似这样的东西:

#define RTL_REG(reg_name,inst)     \
    inst == 0 ? DUT_0_##reg_name : \
    inst == 1 ? DUT_1_##reg_name : \
    inst == 2 ? DUT_2_##reg_name : \
    inst == 3 ? DUT_3_##reg_name : \
    DUT_0_##reg_name

但是代码无法按照我想要的方式工作。本质上是用inst的值代替了定义。

我要寻找的是:

RTL_REG(CLK_EN,0) -> *DUT_0_CLK_EN*

RTL_REG(CLK_EN,1) -> *DUT_1_CLK_EN*

我得到的是什么

RTL_REG(CLK_EN,0) -> 0

一些C专家可以帮我吗?

注意: 尝试在定义的开头和结尾处也添加(),但是在定义替换中再次出现“(”)!

2 个答案:

答案 0 :(得分:0)

你可以做

#define RTL_REG(reg_name,inst) DUT_##inst##_##reg_name

##用于连接两个令牌。参见this

答案 1 :(得分:0)

预处理器不支持条件表达式(如?:)。而是使用单独的函数宏来连接组件:

#define  JOIN4(a, b, c, d)    a##b##c##d
#define  RTL_REG(name, inst)  JOIN4(DUT_, inst, _, name)

这样,RTL_REG(CLK_EN, 0)扩展为DUT_0_CLK_ENRTL_REG(CLK_EN, 1)扩展为DUT_1_CLK_EN

类似于函数的宏调用意味着宏参数在连接之前由预处理器求值。这意味着如果您添加类似

的定义
#define  CLK_EN  CLOCK_ENABLE

然后RTL_REG(CLK_EN, 2)扩展为DUT_2_CLOCK_ENABLE。如果您进一步添加

#define  DUT_  WEIRDPREFIX_

然后,RTL_REG(CLK_EN, 3)会扩展为WEIRDPREFIX_3_CLOCK_ENABLE


假设您不能使用相同的前缀(DUT_0DUT_1)。别担心;您只需要添加一层类似于函数的宏调用,然后重新定义前缀:

#define  JOIN3_(a, b, c)      a ## b ## c
#define  JOIN3(a, b, c)       JOIN3_(a, b, c)
#define  RTL_REG(name, inst)  JOIN3(DUT_ ## inst, _, name)

然后,如果您说了这些附加定义,

#define  DUT_0   FIRST
#define  DUT_1   SECOND
#define  CLK_EN  CLOCK_ENABLE

然后,RTL_REG(CLK_EN, 0)扩展为FIRST_CLOCK_ENABLERTL_REG(CLK_EN, 1)扩展为SECOND_CLOCK_ENABLE。而且,当然,如果您进行其他定义,例如

#define  FIRST_CLOCK_ENABLE   foo(1)
#define  SECOND_CLOCK_EANBLE  bar(2)

然后RTL_REG(CLK_EN, 0)确实扩展为foo(1),并且RTL_REG(CLK_EN, 1)扩展为bar(2)

如果中间术语已经定义为宏,则只需要小心即可,不要太惊讶。如果您使用的是GCC,则可以运行gcc -dD -E source-or-header-file获取包含所有宏定义语句的预处理源。