我有一些宏可以轻松定义寄存器中的位字段(我将它们用于读取,修改,写入操作,设置,获取等)。我收到了一个我不理解的编译器错误。
// 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 ))
有任何帮助吗?感谢。
答案 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个参数)。