On Tuesday 2010-06-01 08:49, Ian Lance Taylor wrote: > >struct list_head { > struct list_head *next, *prev; >}; > >int main(void) >{ > struct list_head clh = {&clh, &clh}; > struct item *pos; > > 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. I could make the containerof macro into a separate, extern, function, so that the optimizer does not cut through the aliasing violation that was intended to be none. extern void *sub(void *x, ptrdiff_t d) { return (char *)x - d; } #define containerof(var, type, member) \ sub(var, offsetof(type, member)) for (pos = containerof(clh.next, typeof(*pos), member)); ... Is there a way I could still make this work, without either making clh a full struct item, or the extern function? Jan