C中的条件#define

问题描述 投票:-1回答:2

我想在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的值代替define。

我想要的是:

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专家吗?

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

c macros
2个回答
0
投票

你可以做到

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

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


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以获取包含所有宏定义语句的预处理源。

© www.soinside.com 2019 - 2024. All rights reserved.