Search code examples
cpointerscastingc11c17

How can one calculate a pointer to the beginning of a struct from a pointer pointing at a member of the struct in a portable way?


Assume T1 and T2 are two types and the following struct is given:

struct s
{
  T1 x;
  T2 y;
}

Further, assume that we have an object of type struct s:

struct s a;

From this, we can calculate a pointer to the second struct member of the object:

T2 *q = &s.y;

What I am looking for is a portable way to calculate from q a pointer p of type struct s * such that p points at the object a.


Solution

  • Given T2 *q = &s.y;, then char *x = (char *) q - offsetof(struct s, y); defines an x that points to the first byte of s. The offsetof macro is defined in <stddef.h>.

    One might then expect struct s *p = (struct s *) x; define a p that points to s, depending on how pedantically one wishes to interpret the C standard. (The conversion of a pointer to char to a pointer to the structure it is the first byte of is not explicitly defined by the standard. We can take the standard’s specification that a pointer “converted back,” in C 2018 6.3.2.3 7, to its original type to cover this case.) I expect it to work in all normal C implementations.