Jan Engelhardt <jengelh@xxxxxxxxxx> writes: > In http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43637 , I had a case > where I apparently ran into strict-aliasing artifacts. As Richard > Guenther points out in comment #2, I may have dereferenced through a > pointer of wrong type. Yet I could not quite spot that yet as I added in > comment #3. > If somebody has a deeper insight into C's spots of undefinedness, a > reply would be greatly appreciated. #ifndef containerof # define containerof(var, type, member) \ (type *)((char *)var - offsetof(type, member)) #endif #define list_entry(ptr, type, member) containerof((ptr), type, member) struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) {&(name), &(name)} #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) ... #define list_for_each_entry(pos, head, member) \ for ((pos) = list_entry((head)->next, typeof(*(pos)), member); \ &(pos)->member != (void *)(head); \ (pos) = list_entry((pos)->member.next, typeof(*(pos)), member)) ... int main(void) { LIST_HEAD(clh); LIST_HEAD(lh); struct item *pos; list_add_tail(&clh, &lh); list_for_each_entry(pos, &clh, list) This is going to expand into for ((pos) = list_entry((&clh)->next, typeof(*(pos)), member); ==> for ((pos) = containerof(((&clh)->next), typeof(*(pos)), member) ==> for ((pos) = (typeof(*(pos)) *)((char *)((&clh)->next) - offsetof(...) At this point you are starting with the field clh.next, which has type "struct list_head", you are casting to to "char *", and you are accessing it as type "struct item *". That is an aliasing violation. Your comment discusses valid memory regions, but that is not the issue. Standard C does not permit you to declare a field to have one type and to access it as a different type; there are certain limited exceptions which do not apply here. Ian