【问题标题】:decoding the offset macro解码偏移宏
【发布时间】:2015-08-28 02:11:08
【问题描述】:

我试图理解 c 中的偏移宏,但在尝试解释时遇到了问题

&((type *)0)

#define offsetof(type, member) ((size_t) &((type *)0)->member)

我如何阅读它。我了解其功能,但不了解该术语的确切解释。

谢谢

【问题讨论】:

    标签: c linux struct macros


    【解决方案1】:

    这个预处理器宏的扩展:

    #define offsetof(type, member) ((size_t) &((type *)0)->member)
    

    导致以下正式定义:给定type 上的offsetof 是给定typemember 成员地址的size_t 的转换。在空指针地址

    或者,换句话说,这是获取member的地址的黑魔法,就好像type的对象存在于空指针地址(注意:只要这里没有发生读取或写入,就不会崩溃)。由于此类成员的地址现在是绝对的(相对于零),因此可以将其值安全地转换为 size_t,从而有效地将此类 member 的偏移量计算为绝对值。

    希望这会有所帮助!

    【讨论】:

    • 如果空指针与值0 不同,您就会遇到麻烦。沙丁鱼确实很好地做到了这一点。所以,我不会称其为“黑魔法”,而是“肮脏(但通常有效)的黑客”。已被 C11 取代。
    • @Olaf:嗯,我对“黑魔法”和“污垢(但经常工作)黑客”的定义相同。你说得对,空指针不一定等于零。但是offsetof 无论如何都是/是实现定义的,因此假设在 OP 正在调查的平台中,空指针的值确实为零。
    【解决方案2】:

    看看这段代码:

    type *x = 0;
    size_t y = &x->member;
    

    通常,y 将等于 x+offset,但因为 x=0,我们只能得到偏移量。

    在代码中我们写((type *)0)——直接返回指向type类型0的指针,而不创建x变量,然后我们获取成员((type *)0)->member)的地址。所有这些都被定义为size_t 变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 2013-03-15
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多