调用宏时参数过多

Posted

技术标签:

【中文标题】调用宏时参数过多【英文标题】:Too many argument in invocation of macro 【发布时间】:2018-05-25 10:37:02 【问题描述】:

当我定义下面的宏时,代码编译得很好:

 #define RSC_HWIO_INXFI(client,drvID,reg,index,field)    HWIO_INXFI((APCS_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), APCS_RSCC_##reg,index,field) 

但是当我包含条件运算符以包含更多客户端/目标时,我收到错误“”

#define RSC_HWIO_INXFI(client,drvID,reg,index,field)    \
                    (APCS_RSCC         == client ? HWIO_INXFI((APCS_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), APCS_RSCC_##reg,index,field) : \
                    (MSS_RSCC          == client ? HWIO_INXFI((MSS_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), MSS_RSCC_##reg,index,field) : \
                    (MSS_QDSP6SS_RSCC  == client ? HWIO_INXFI((MSS_QDSP6SS_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), MSS_QDSP6SS_RSCC_##reg,index,field) : \
                    (AOP_RSCC          == client ? HWIO_INXFI((AOP_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), AOP_RSCC_##reg,index,field) : HWIO_INXFI((APCS_RSCC_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), APCS_RSCC_##reg,index,field)))))

需要注意的是,该错误仅针对最后 3 个客户端,即 MSS_RSCC、MSS_QDSP6SS_RSCC 和 AOP_RSCC。不是第一个(APCS_RSCC)

有什么线索吗?

问候,

【问题讨论】:

首先,请不要标记多种语言,仅使用您实际编程语言的标记。其次,请尝试创建一个Minimal, Complete, and Verifiable Example,其中包含所有相关宏以及您如何使用您向我们展示的宏。最后,请将 fullcomplete 错误复制粘贴到问题正文中,包括可能的信息说明。 看起来你会更容易逃脱:HWIO_INXFI((client##_RSCC_RSC_REG_BASE+RSC_DRV_OFFSET(drvID)), client##_##reg,index,field)... XYZ_RSCC 是指针吗?如果不是,请注意预处理器解析比较,因此如果 XYZ_RSCC 本身不作为符号存在,XYZ_RSCC == client 之后将无法编译! @Aconcagua 为什么需要指针?它也适用于宏、枚举或其他标识符。 您在使用该宏时提供了哪些参数?他们有什么类型?请提供如上所述的 MCVE。 【参考方案1】:

您在宏中引入了比较:

APCS_RSCC == client

这只有在 APCS_RSCC 本身是一个有效的 C 标识符时才有效。预处理器不会解析这些比较,而是将它们留给编译器。然后,APCS_RSCC 可能是另一个宏,它解析为某种指针(例如,一个包含多个地址的结构),或者只是一些裸地址(APCS_RSCC_RSCC_RSC_REG_BASE 然后可能解析为 (APCS_RSCC->RSCC_RSC_REG_BASE) 或 @ 987654325@。不过,命名并没有给我这样定义的印象......

现在可以使用串联:

#define RSC_HWIO_INXFI(client,drvID,reg,index,field)       \
HWIO_INXFI(                                                \
    client##_RSCC_RSC_REG_BASE + RSC_DRV_OFFSET(drvID),    \
    client##_##reg,index,field                             \
)                                                          \

好的,现在你在 cmets 中告诉我这个宏没有编译。假设原始宏有效,奇怪的是,当您在同一级别连接时:

#define RSC_HWIO_INXFI(client,drvID,reg,index,field)       \
HWIO_INXFI(                                                \
    (APCS_RSCC_RSCC_RSC_REG_BASE + RSC_DRV_OFFSET(drvID)), \
    APCS_RSCC_##reg, index, field                          \
)
//            ^^

您可以通过间接连接来规避该问题(类似于字符串化,您是否已经遇到过这些宏?):

#define RSC_HWIO_INXFI(client, drvID, reg, index, field)           \
HWIO_INXFI(                                                        \
    CONCAT3(client, _, RSCC_RSC_REG_BASE) + RSC_DRV_OFFSET(drvID), \
    CONCAT3(client, _, reg), index, field                          \
)
#define CONCAT3(X, Y, Z) X##Y##Z

【讨论】:

以上是关于调用宏时参数过多的主要内容,如果未能解决你的问题,请参考以下文章

调用类方法 - 输入参数过多

有没有一种方法可以将宏名称作为参数传递给嵌套宏,而不会在扩展最外层的宏时扩展它们?

在子类中调用抽象基类方法时位置参数错误过多

不能在验证参数中使用模拟函数调用:调用次数过多

MATLAB 奇怪的“输入参数过多”错误

高分求助VC中关于不定参数宏的使用