【问题标题】:Why this 0 in ((type*)0)->member in C?为什么这个 0 在 ((type*)0)->C 中的成员?
【发布时间】:2012-11-23 06:57:40
【问题描述】:

Linux内核中的container_of()宏定义为:

#define container_of(ptr, type, member) ({ \
        const typeof( ((type*)0)->member) * __mptr =(ptr);\
        (type*)( (char*)__mptr - offsetof(type,member) );})

为什么这里使用((type*)0)->member,而不是(type*)->member?

【问题讨论】:

  • 看起来有人试图将 null 转换为 type*,然后访问它的成员成员。
  • @Nocturno 不只是尝试。 :)

标签: c kernel


【解决方案1】:

为什么这是 ((type*)0)->member,而不是 (type*)->member

仅仅是因为(type*)->member 是无效的语法,因此typeof 是不可能的。所以它使用了一个NULL 指针,它无论如何都不会取消引用——它只是为了让typeof 可以引用该成员。


这是如何工作的:

  • typeof 技巧用于声明成员类型的指针。这个指针gets是用调用者传递的指针初始化的

  • 从指针地址中减去该成员在结构中的偏移量:这会产生包含对象的地址


更微妙的问题:为什么不摆脱typeof而只做ptr - offsetof。无论如何,我们将其转换为char *,对吗?在这种情况下,您可以将任何内容作为ptr 传递,编译器不会说什么。所以整个typeof 的东西都用于(基本的)类型检查。

【讨论】:

    【解决方案2】:

    因为type* 是一种类型,而不是结构的有效实例。

    指向零的指针用于获取正确的实例,但由于typeof 在编译时而不是在运行时解析,因此指针中使用的地址不必是正确或有效的地址。

    【讨论】:

      猜你喜欢
      • 2012-12-05
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 2022-11-03
      • 2020-04-02
      • 1970-01-01
      • 2014-12-30
      相关资源
      最近更新 更多