[Mesa-dev] [PATCH 08/13] util/list: Add C99-based iterator macros

Neil Roberts neil at linux.intel.com
Tue May 5 11:13:00 PDT 2015

Jason Ekstrand <jason at jlekstrand.net> writes:

> +#define list_for_each_entry(type, pos, head, member)                    \
> +   for (type *pos = container_of((head)->next, pos, member);            \
> +	&pos->member != (head);                                         \
> +	pos = container_of(pos->member.next, pos, member))

I think this is technically invalid. The container_of macro dereferences
the pos pointer but at this point it is undefined so I think the
compiler is allowed to do whatever it wants here. There is a comment
above the container_of macro saying exactly that.

Some quick testing with clang shows that it actually takes advantage of
this undefined behaviour and doesn't add the offset to pos to get the
container and it all falls apart.

A while ago we added the wayland linked-list implementation to Cogl and
we ran into a similar problem. We actually ended up changing the
container_of macro to take a type instead of a sample pointer because
this is such an easy trap to fall into.


- Neil

More information about the mesa-dev mailing list