.. can you convert from an int * pointing to an i field to a struct S *?
Answer: Yes, but ...
Based on
Pointer
Notes
Although any pointer to object can be cast to pointer to object of a different type, dereferencing a pointer to the type different from the declared type of the object is almost always undefined behavior. See strict aliasing for details.
and
Strict aliasing
Given an object with effective type T1, using an lvalue expression (typically, dereferencing a pointer) of a different type T2 is undefined behavior, unless:
- T2 is a character type (char, signed char, or unsigned char)
and
offsetof
The macro offsetof expands to an integer constant expression of type size_t, the value of which is the offset, in bytes, from the beginning of an object of specified type to its specified subobject, including padding if any.
it should be alright, but here is the issue:
Pointer arithmetic
For the purpose of pointer arithmetic, a pointer to an object that is not an element of any array is treated as a pointer to the first element of an array of size 1.
The behavior is defined only if both the original pointer and the result pointer are pointing at elements of the same array or one past the end of that array. Note that executing p-1 when p points at the first element of an array is undefined behavior and may fail on some platforms.
- If the pointer P1 points at an element of an array with index I (or one past the end) and P2 points at an element of the same array with index J (or one past the end), then
- P1-P2 has the value equal to I-J and the type ptrdiff_t (which is a signed integer type, typically half as large as the size of the largest object that can be declared)
The behavior is defined only if the result fits in ptrdiff_t.
Although, we know (assuming the parameter i
of the function really points to a member of struct S
), that the pointer is pointing to a valid region in memory (begin of struct S
), the compiler might not see it that way. But i am not a language lawyer and since the comments above mentioned the usage in the linux kernel, i will and cannot come to a final assessment.