pho*_*594 4 c macros c-preprocessor
问题
我正在做一些固件编码,并有很多位掩码来管理.到目前为止,我一直在为每个要掩盖的字段重复相同的块,如下所示:
#define LinkStateMask 0x1
#define LinkStateShift 8
#define LinkState(x) (((x) >> LinkStateShift) & LinkStateMask)
Run Code Online (Sandbox Code Playgroud)
请注意,这些字段通常是多位字段,因此并不总是保证掩码0x1.最终的宏可以很容易地在代码中使用,这是我非常喜欢的:
if( LinkState(temp) == 0 ) {
// Link is down, return error
return -ENODEV;
}
Run Code Online (Sandbox Code Playgroud)
问题
有没有办法让C预处理器为我生成这些宏?我知道预处理器只能在一次通过中工作,所以宏不能直接定义另一个,但希望还有另一种方法.
理想情况下,我想写一些类似于以下内容的东西,并使用与上面第二个清单相同的C代码:
BIT_FIELD(LinkState, 8, 0x1) // BIT_FIELD(name, lsb, mask)
Run Code Online (Sandbox Code Playgroud)
对我来说,关键是在主C文件中保留符号命名的函数式用法,而不必在BIT_FIELD(...)每次需要生成掩码时编写整个调用(其中一些字段被广泛使用,导致维护噩梦).
最后一个限制:我需要的字段稀疏地分散在数百个寄存器中.如果可能的话,我真的想避免struct为每个人定义一个,因为我通常只需要一个或两个字段.
小智 5
宏不能定义另一个宏,但它可以调用另一个宏(预处理器不会停止,直到没有非终端为止)
那么,这样的事情怎么样?至少节省一些打字......
#include <stdio.h>
#define SHIFTMASK(x,s,m) (((x) >> (s)) & (m))
#define LinkState(x) SHIFTMASK(x, 8, 0x1)
#define Whatever(x) SHIFTMASK(x, 9, 0x7)
int test[] = { 0x0f00, 0x0a01, 0x0100, 0x0007 };
int main()
{
int i;
for (i = 0; i < 4; ++i)
{
printf("test[%d]: 0x%x\n", i, test[i]);
printf("LinkState(test[%d]): 0x%x\n", i, LinkState(test[i]));
printf("Whatever(test[%d]): 0x%x\n", i, Whatever(test[i]));
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)