I'm going to assume when you have struct_second_t
you actually meant second_struct_t
, otherwise your code does not compile.
The problem is that f
in some_struct
is a pointer to a first_struct_t
not a pointer to a second_struct_t
.
I should add that the cast in struct_second_t *s = (struct_second_t *) p->f;
is hiding the warning message. In general if you have to cast one pointer to another you are more often than not going to cause undefined behavior. This is not always true but is a pretty good guideline.
In response to comment.
First it appears you will not get that warning with gcc for x86 (32 and 64 bit) as there is no alignment requirement for general purpose registers although alignment can improve performance (see this SO post for more info). As to why clang emits that warning, perhaps because of performance or they do not have the exception as gcc does for x86.
Second what you are trying to accomplish is similar to what the container_of
macro does in the Linux kernel. container_of
is typically defined as:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
In searching the only thing I have found that addresses your issue is this commit to tup that changed their version of container_of
to include a cast to void*
.
Basically, I believe the issue is while you know that p->f
actually points to a second_struct_t
your compiler does not and therefore issues the warning. So you can either not do that or cast to void*
.
Additional:
It seems mozilla address the issue by casting to void*
as well:
Finally, I would recommend looking at container_of
and using that instead of relying on the fact that the first element of the struct is the other struct. This way your code is more resilient, if someone else changes the order of the struct members it will still work. You will have to add a void*
cast to container_of
to avoid the warning. Note that on architectures with alignment issues, you should not have an issue at runtime assuming you always do your type change between child and parent correctly.