功能宏的函数宏参数

时间:2014-03-11 17:23:50

标签: c macros c-preprocessor

我有一些宏可以轻松定义寄存器中的位字段(我将它们用于读取,修改,写入操作,设置,获取等)。我收到了一个我不理解的编译器错误。

// used just for named arguments -- to make the values more clear when defined
#define FLDARGS(dwOffset, bitStart, bitLen) dwOffset, bitStart, bitLen
// extract just the dwOffset part
#define FLD_DWOFFSET(dwOffset, bitStart, bitLen) dwOffset

// define a bit field
#define CFGCAP_DEVCTRL FLDARGS(2, 16, 4)

// in a function:

uint32_t dwAddr = addr/4;
// compare just the dwOffset part
if(dwAddr == FLD_DWOFFSET( CFGCAP_DEVCTRL ))
{
 // do something
}

我希望这会扩展为: CFGCAP_DEVCTRL = 2,16,4

FLD_DWOFFSET(CFGCAP_DEVCTRL)= 2

我收到了gcc错误:

error: macro "FLD_DWOFFSET" requires 3 arguments, but only 1 given
      if(dwAddr == FLD_DWOFFSET( CFGCAP_DEVCTRL ))
                                                ^
error: ‘FLD_DWOFFSET’ was not declared in this scope
      if(dwAddr == FLD_DWOFFSET( CFGCAP_DEVCTRL ))

有任何帮助吗?感谢。

3 个答案:

答案 0 :(得分:1)

让我们看看你的宏将如何处理:

if(dwAddr == FLD_DWOFFSET( CFGCAP_DEVCTRL ))

首先,它尝试替换最外面的宏,即FLD_DWOFFSET。但它需要3个参数,当你只提供1时(你的内部宏尚未解析)。预处理器不能再进一步,因此错误。

此处有更多相关信息:http://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls

答案 1 :(得分:1)

宏传递按照找到的顺序扩展宏。要找到的第一个宏是FLD_DWOFFSET( stuff ),它只能看到一个参数CFGCAP_DEVCTRL,因此无法扩展FLD_DWOFFSET宏。在当前扩展完成之前,它不会尝试扩展更多的宏 - 换句话说,它不会识别CFGCAP_DEVCTRL是一个宏,直到它完成扩展FLD_DWOFFSET,但它不会这样做因为你没有提供足够的论据......

答案 2 :(得分:0)

其他答案正确告诉我为什么我不能做我想做的事情。 FLD_DWOFFSET正在使用一个未展开的arg进行评估。

这是我的解决方案:

static inline uint32_t FLD_DWOFFSET(int dwOffset, int bitStart, int bitLen){return dwOffset;}

希望这与优化相同。由于它是一个函数,因此在调用之前会扩展宏参数(扩展为3个参数)。