4

有一个结构

typedef struct _pack_t {
    char tag[4];     
    int type;                
    size_t size;              
    size_t offset;           
    char data[0];           
} __attribute__((packed)) pack_t;

并且有一个定义

#define PACK_OFFSET ((size_t)((pack_t *)0)->data)

定义是什么意思?以及如何理解指针“0”?

4

4 回答 4

4

这是一个预处理器宏。data它产生结构成员的偏移量pack_t。当其封闭结构的基地址为零时,它通过获取该成员的绝对地址来做到这一点。

对于非 NULL 指针,这可以通过声明任何类型的变量pack_t然后获取结构地址和成员地址的差异来完成,两者都以字节为单位,如下所示:

pack_t dummy;
size_t offset = (char *)&dummy.data - (char *)&dummy;

(但这不仅是无效的,因为减去的两个指针不指向同一个数组的元素,而且它还需要一个多余的局部变量,由于各种原因,人们不想要它。这就是为什么它巧妙地使用 a空指针。)

(不要因为没有看到 addressof ( &) 运算符而感到困惑 -data是一种数组类型,因此它会衰减为指向其第一个元素的指针。)

于 2013-03-29T10:01:02.167 回答
3

这是您的字段数据的偏移量struct _pack_t(pack_t *) 0是 NULL 指针,类型为 pack_t。请注意,字段数据的长度为 0,表示“变量”:它必须由某个函数填充。

前任:memcpy((char *) packet + PACK_OFFSET, data, data_len);

于 2013-03-29T10:01:35.833 回答
1

让我们想象一个黑板

老师看到的地方

PACK_OFFSET

(s)他把橡胶板拿出来擦洗PACK_OFFSET并用

((size_t)((pack_t *)0)->data)
于 2013-03-29T10:04:22.040 回答
1

我不是在回答你的问题,我只是举一个例子来支持 H2CO3 的观点。要正确获取结构成员的偏移量,它必须是 0 指针。代码如下:

typedef struct _pack_t {
    char tag[4];     
    int type;                
    size_t size;              
    size_t offset;           
    char data[0];           
}pack_t;

#define OFFSET_0 ((size_t)((pack_t *) 0)->data)
#define OFFSET_1 ((size_t)((pack_t *) 1)->data)
#define OFFSET_2 ((size_t)((pack_t *) 2)->data)

int main(void){

    printf("%lu\n", OFFSET_0);
    printf("%lu\n", OFFSET_1);
    printf("%lu\n", OFFSET_2);
    return 0;
}

输出:

24
25
26
于 2013-03-29T10:17:05.133 回答