我想用用参数控制的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专家可以帮我吗?
注意: 尝试在定义的开头和结尾处也添加(),但是在定义替换中再次出现“(”)!
答案 0 :(得分:0)
答案 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_EN
,RTL_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_0
,DUT_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_ENABLE
,RTL_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
获取包含所有宏定义语句的预处理源。