【问题标题】:structure offset macro [duplicate]结构偏移宏
【发布时间】:2012-12-12 12:04:11
【问题描述】:

可能重复:
Why does this C code work?

我确实看到定义了一个宏来计算结构偏移量,如下所示

#define offsetof(st, m) ((size_t)(&((st *)0)->m))

但我不明白这个定义是如何工作的。看起来结构的成员是通过NULL 指针访问的。谁能详细说明这个表达式是如何工作的?

【问题讨论】:

  • 指针实际上并没有被取消引用。

标签: c pointers struct offset


【解决方案1】:

1) 首先创建一个指向“st”类型结构的空指针:(st *)0

2) 接下来取这个结构的成员:->m

3) 接下来获取成员的地址:&(...)

4) 最后将成员的地址转换为 size-t 类型:(size_t)(...)

工作发生在第 3 步,因为指针为空(即地址 == 0),然后成员的地址仅包含结构内的成员位置。

【讨论】:

    【解决方案2】:

    此表达式在编译时进行了优化,从而在您的程序中产生一个编译时偏移值。

    编译器看到一个常量指针 (0),看到一个常量偏移量,然后只应用 constant folding,生成地址 0 + offset(== 偏移量),这正是我们所需要的。

    有趣的是,这是否可以在没有任何优化的情况下工作,或者总是进行一些基本的常量折叠。

    附:更准确地说,这种优化称为Scalar Replacement of Aggregates,正如下面雷某所指出的那样。

    【讨论】:

    • 感谢您指出这是由于编译器优化造成的。但是,根据我对 clang 和 opt 的尝试,传递“聚合的标量替换”实际上将此宏转换为常量。
    • @LeiMou 是的,这个优化的更准确的名字。我刚刚应用了我在 Coursera 的“编译器”中获得的知识来为这种行为命名 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 2017-09-25
    相关资源
    最近更新 更多