让我们从代码和错误开始。
#define BitMap_getMask(range) (((~(unsigned int)0>>(31-range.b+range.a))<<range.a))
#define BitMap_get(x, range) (x & BitMap_getMask(range))
#define awesome (range){4,6}
...................
printf("%08x\n", BitMap_get(0xEEEEEEEE, awesome));
现在来自编译器的错误。第29行,与printf的行。
错误:宏&#34; BitMap_getMask&#34;通过2个参数,但只需1个 错误:&#39; BitMap_getMask&#39;未申报(首次使用此功能)
我正在开发一个小型库,它可以帮助我进行按位操作。当尝试在另一个宏中使用宏时,我收到此错误。
答案 0 :(得分:3)
这可能就是你需要的
#define BitMap_getMask(range) \
(((~(unsigned int) 0 >> (31 - (range).max + (range).min)) << (range).min))
#define BitMap_get(x, range) \
((x) & BitMap_getMask(range))
#define awesome \
((struct {int min; int max;}){4, 6})
错误是由于{4, 6}
的扩展。
答案 1 :(得分:3)
当范围扩展到{4,6}并传递给BitMap_getMask时,你得到的是BitMap_getMask({4,6}),它是2个参数,而BitMap_getMask需要1个参数。
此外,预处理器仅对这些宏进行文本替换。它不知道类型。它将用文本“{4,6}”替换文本“范围”的每个实例,因此您没有可以使用的类型(结构范围)或类型实例,只有一些文本,所以“范围。一个“和”range.b“也不起作用;它们会产生类似“{4,6} .a”和“{4,6} .b”
的结果无效C。
C99支持内联函数,现在几乎没有理由在C中使用预处理器宏。他们很麻烦(一个好用的当然是包括警卫)。内联函数位于编译器的域中并进行了正确的类型检查。
struct awesome
{
unsigned int a;
unsigned int b;
};
...
static inline unsigned int BitMap_get(unsigned int x, awesome range)
{
return (x & BitMap_getMask(range));
}
static inline unsigned int BitMap_getMask(awesome range)
{
return (((~(unsigned int)0>>(31-range.b+range.a))<<range.a));
}
...
awesome range =
{
.a = 4,
.b = 6,
};
unsigned int x = 0xEEEEEEEE;
unsigned int bm = BitMap_get(x, awesome);
...