如何理解宏定义

时间:2018-01-28 15:19:26

标签: c++ macros

我不是C ++程序员,在源代码中遇到以下宏定义:

// HACK: gcc warns about applying offsetof() to non-POD object or calculating
//       offset directly when base address is NULL. Use 16 to get around the
//       warning. gcc-3.4 has an option -Wno-invalid-offsetof to suppress
//       this warning.
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)

我感到困惑的事实是:

  1. ((klass*)16)->field)将16转换为klass*然后隐藏到字段field

  2. (intx)&(...)按位或使用intx或强制转换为引用某种类型intx

  3. intx的定义如下:

    typedef intptr_t  intx
    

3 个答案:

答案 0 :(得分:4)

这种宏的目的是获取结构中特定字段的内存偏移量。这并不罕见。

要解释详细信息,(klass*)16会将16转换为指针,然后(intx)&(((klass*)16)->field)会查看字段field的地址,并将此地址解释为整数。结合以下减去16,获得该字段的偏移量。

例如:

#define offset_of(klass,field) (size_t)((size_t)&(((klass*)16)->field) - 16)

struct foo {
    int   a;
    char  b;
    short c;
};

int main() {
    size_t offset_of_b = offset_of(foo, b);
}

此处offset_of_b只是结构b中字段foo的内存偏移量。

答案 1 :(得分:1)

在这种情况下,&是地址运算符,在field类型中采用klass的地址。

其余部分只是括号问题,以确保在正确的位置获得RIGHT位,并进行多次转换以确保指向field的指针是一个整数类型,可以强制转换为{{1} }。

答案 2 :(得分:1)

此宏用不同的代码替换其行为未定义的代码,其行为也未定义,以避免警告第一个版本的行为未定义。

试图分析其工作原理"是一个客厅游戏。这不是工程。这就是为什么它被标记为" HACK"。