【问题标题】:How do you use offsetof() on a struct?如何在结构上使用 offsetof()?
【发布时间】:2011-08-24 18:17:19
【问题描述】:

我想要mystruct1 中的param 行的offsetof()。我试过了

offsetof(struct mystruct1, rec.structPtr1.u_line.line) 

还有

offsetof(struct mystruct1, line)  

但两者都不起作用。

union {
    struct mystruct1 structPtr1;
    struct mystruct2 structPtr2;
} rec;

typedef struct mystruct1 {
    union {
        struct {
            short len;
            char buf[2];
        } line;

        struct {
            short len;
        } logo;

    } u_line;
};

【问题讨论】:

  • 您不能为我们提供结构定义的可编译代码吗?或者省略struct mystruct2...
  • 你说的“都不行”是什么意思?
  • 请注意,此示例中不需要关键字typedef。这是一个空洞的用法,因为没有给出名称来成为struct mystruct1 的别名。

标签: c


【解决方案1】:

offsetof() 宏有两个参数。 C99 标准说(在 §7.17 <stddef.h>):

offsetof(type, member-designator)

它扩展为一个类型为size_t 的整数常量表达式,其值为 这是结构成员(由成员指定器指定)的字节偏移量, 从其结构的开头(按类型指定)。类型和成员代号 应该是给定的

static type t;

然后表达式&(t.member-designator) 计算为地址常量。

所以,你需要写:

offsetof(struct mystruct1, u_line.line);

但是,我们可以观察到答案将为零,因为 mystruct1 包含一个 union 作为第一个成员(也是唯一的),并且它的 line 部分是联合的一个元素,所以它会位于偏移量 0。

【讨论】:

【解决方案2】:

关于这方面的一篇很棒的文章是:

Learn a new trick with the offsetof() macro

我在我的嵌入式代码中经常使用 offsetof 宏,以及文章中讨论的修改后的 SIZEOF 宏。

【讨论】:

    【解决方案3】:

    您的 struct mystruct1 有 1 个名为 u_line 的成员。你可以看到那个成员的偏移量

    offsetof(struct mystruct1, u_line); // should be 0
    

    如果您指定每个“父母身份级别”,则为下一行成员

    offsetof(struct mystruct1, u_line.line);
    offsetof(struct mystruct1, u_line.line.buf);
    offsetof(struct mystruct1, u_line.logo);
    

    【讨论】:

      【解决方案4】:

      首先,AFAIK,offsetof 仅用于结构的直接成员(我说得对吗?)。

      其次,了解流行的offsetof 实现的内部细节,我建议尝试一下

      offsetof(struct mystruct1, u_line.line) 
      

      这应该可行。它是否符合标准对我来说是一个悬而未决的问题。

      附:从@Jonathan Leffler 的回答来看,这应该确实有效。

      【讨论】:

      • “我说得对吗?”我不这么认为(在测试 gcc 之后)。 gcc 在offsetof 表达式上接受“深层”成员。
      • @pmg:嗯,像这样的问题并不能真正通过“测试”来回答。
      • 对@Andrey。乔纳森的回答中发布的标准引用允许将offsetof 与“深度”成员一起使用。
      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 2011-06-10
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多