【问题标题】:What's the mean of "#define PACK_OFFSET ((size_t)((pack_t *)0)->data)"“#define PACK_OFFSET ((size_t)((pack_t *)0)->data)”是什么意思
【发布时间】:2023-04-06 11:00:01
【问题描述】:

有一个结构

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”?

【问题讨论】:

  • offsetof(pack_t, data)意思一样

标签: c pointers c-preprocessor


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    例如:memcpy((char *) packet + PACK_OFFSET, data, data_len);

    【讨论】:

      【解决方案3】:

      让我们想象一个黑板

      老师看到的地方

      PACK_OFFSET
      

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

      ((size_t)((pack_t *)0)->data)
      

      【讨论】:

        【解决方案4】:

        我不是在回答你的问题,我只是举一个例子来支持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
        

        【讨论】:

          猜你喜欢
          • 2011-07-31
          • 1970-01-01
          • 2011-09-24
          • 2020-10-02
          • 1970-01-01
          • 1970-01-01
          • 2015-03-20
          • 2020-01-07
          • 2018-09-10
          相关资源
          最近更新 更多