------- Comment #3 from jengelh at medozas dot de 2010-05-26 21:44 ------- >You are accessing {lh,clh}.{next,prev} through a pointer to type struct item.
Thank you for your time. I do have a few questions. I wonder where exactly I am doing that access. In the first part of the for clause, (pos) = list_entry((head)->next, typeof(*(pos)), member); head->next is valid, so only pos is punned. The second part is &(pos)->member != (void *)(head); This I can imagine blowing up; as pos will point to a non-existing memory block once the end of the list is reached. I thus replace that by the reverse of containerof to avoid dereferencing pos (/or accessing member/next through a pointer of the wrong type), IOW #define s_member(var, type, member) \ ((type *)((char *)var + offsetof(typeof(*var), member))) s_member(pos, struct list_head, member) != (void *)(head) On an empty list, the condition is not met, so the for loop stops and the third part of the for() is not evaluated. On a non-empty list, pos points to a valid memory region as long as it loops, so that the pos->member.next in 3rd part, (pos) = list_entry((pos)->member.next, typeof(*(pos)), member)) should be valid. Please correct me if I am wrong. Though I also have to employ s_member in the third case (pos) = list_entry(s_member((pos), struct list_head, member)->next, typeof(*(pos)), member)) to get rid of any visible artifacts (such as segfaults), but I suspect the underlying problem isn't eliminated. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43637