Consider the following code that starting with GCC 4.1.0 generates 'dereferencing type-punned pointer will break strict-aliasing rules' warning:
~> cat test.c struct inner { struct inner *next; }; struct outer { struct inner base; int value; }; /* List of outer elements where all outer.base.next point to struct outer */ struct outer_list { struct outer *head; }; struct outer *search_list(struct outer_list *list, int value) { struct outer *elem, **pelem; pelem = &list->head; while ((elem = *pelem)) { if (elem->base.value == value) { /* Hit, move atom's element to the front of the list. */ *pelem = (struct outer*)elem->base.next; elem->base.next = &list->head->base; list->head = elem; return elem; } /*** LINE GENERATING WARNING */ pelem = (struct outer **)&elem->base.next; } return 0; } ~> gcc -c -Wall -O2 test.c test.c: In function 'search_list': test.c:29: warning: dereferencing type-punned pointer will break strict-aliasing rules But why the warning is generated? Doesn't it guaranteed that offsetof(struct outer, base) == 0 and one can always safely cast struct inner* to struct outer* if struct inner is a part struct outer so struct* outer can alias struct* inner?