如何以一种可移植的方式从指向该结构的成员的指针中计算出指向该结构的开头的指针?

时间:2018-12-22 12:09:29

标签: c pointers casting c11 c17

假设T1T2是两种类型,并给出以下结构:

struct s
{
  T1 x;
  T2 y;
}

进一步,假设我们有一个struct s类型的对象:

struct s a;

由此,我们可以计算出指向对象第二个struct成员的指针:

T2 *q = &s.y;

我正在寻找一种可移植的方法,可根据q计算类型为p的指针struct s *,使得p指向对象a

3 个答案:

答案 0 :(得分:4)

给出T2 *q = &s.y;,然后char *x = (char *) q - offsetof(struct s, y);定义一个指向x的第一个字节的soffsetof宏在<stddef.h>中定义。

然后可能会期望struct s *p = (struct s *) x;定义指向p的{​​{1}},这取决于人们对C标准的理解程度。 (标准中并未明确定义将指向s的指针转换为指向它的第一个字节的结构的指针。我们可以采用标准的规范,即在C 2018 6.3中将指针“转换回”。 .2.3 7,以涵盖这种情况的原始类型。)我希望它能在所有常规C实现中使用。

答案 1 :(得分:1)

您正在寻找container_of();来自Wikipedia

#define container_of(ptr, type, member) ((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))

或更简单但更不安全

#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))

在您的情况下,您应将其应用

struct *s = container_of(q, struct s, y);

答案 2 :(得分:-1)

T2 *py = &z.y

T1 *px = (T1 *)((char *)py - ((char *)&z.y - (char *)&z.x));