在另一个宏声明中使用宏

时间:2015-01-21 17:28:49

标签: c macros c-preprocessor

让我们从代码和错误开始。

#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;未申报(首次使用此功能)

我正在开发一个小型库,它可以帮助我进行按位操作。当尝试在另一个宏中使用宏时,我收到此错误。

2 个答案:

答案 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);
...