C++获取结构体成员偏移量

起因

朋友最近发来一段代码,自己刚看到代码懵了一会儿,特此记录一下
代码如下:

struct Base
{
    uint8_t  a;
    uint32_t b;
};

int main()
{
     auto n = (intptr_t)(&((Base*)0)->b);
    cout << n << endl;
}

上面定义了一个结构体类型Base,main函数里面输出的值是多少?起初自己认为将常量0强转为Base*,再访问成员变量b,是一个ub操作,n的值无意义,后来发现输出n的值为1。

经过了解才明白这个是获取结构体成员偏移量常用的手法,上面代码将常量0转换为指针再访问b,确实是非法的操作,不过前面的取地址符其实是合法的,因为转换后的首地址为0,取成员变量b的地址,就等于b的偏移量,而uint8_t是1个字节,所以b的偏移量是1(当然这里是没有考虑内存对齐的结果,如果考虑内存对齐的话,b的偏移量就是4了)。

最后

在项目里,如果我们有许多计算结构体成员偏移量的情况,可以定义一个宏来到达我们的目的
例如:

#define OFFSET(TYPE,MEMBER) (intptr_t)(&((TYPE*)0)->MEMBER)

留下评论