[PATCH 1/4] utils: Document wl_container_of

Kristian Høgsberg hoegsberg at gmail.com
Wed Sep 11 10:47:03 PDT 2013


On Wed, Aug 28, 2013 at 06:01:59PM -0500, Aaron Faanes wrote:
> The explanation added is admittedly verbose (and reads more like a
> proof), but my hope is that the comment should demystify how
> wl_container_of works for those not familiar with the technique used.
> Understanding this function also helps understanding how wl_list works.

Hi Aaron,

I think it would be good to document wl_container_of, but I feel that
this is a little to verbose.  Maybe we can just describe what it does
and not how it does it?  Also, it's not specific to wl_list, it can be
used anywhere you have a pointer to a field in the struct and want to
work your way back to a pointer to the struct.

Kristian

> ---
>  src/wayland-util.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/src/wayland-util.h b/src/wayland-util.h
> index e5e4e25..02d9458 100644
> --- a/src/wayland-util.h
> +++ b/src/wayland-util.h
> @@ -110,6 +110,51 @@ int wl_list_length(const struct wl_list *list);
>  int wl_list_empty(const struct wl_list *list);
>  void wl_list_insert_list(struct wl_list *list, struct wl_list *other);
>  
> +/**
> + * Retrieves a pointer to the content of a wl_list item.
> + *
> + * The ptr is a pointer to the wl_list item.
> + *
> + * The sample must be a pointer to the type of content that the list item
> + * stores, though it need not be a "valid" pointer; a null pointer will
> + * suffice.
> + *
> + * The member is the named location of ptr within the content.
> + *
> + * For instance, using the example above, assume the following list of
> + * integers:
> + *
> + * 	struct item_t {
> + * 		int foo;
> + * 		struct wl_list link;
> + * 	};
> + *
> + * Which lays out this content in memory like so:
> + *
> + * [content......][wl_list item][trailing content...]
> + *
> + * To retrieve a pointer to content given a pointer to its link, you would
> + * need to retrieve this size:
> + *
> + * [content......][wl_list item][trailing content...]
> + * ^-------------^
> + *
> + * Since we know the link is within item_t, we can retrieve a relative
> + * position of that link using subtraction:
> + *
> + * struct item_t *sample = NULL;
> + * offset = &(sample->link) - sample;
> + *
> + * This offset will be valid even if sample is a null or invalid pointer since
> + * we never dereference it; we only perform pointer arithmetic on it.
> + *
> + * Finally, with the offset and the given link, we can retrieve a pointer to
> + * content and complete the macro:
> + *
> + * content = link - offset;
> + * content = link - (&(sample->link) - sample);
> + * content = ptr  - (&(sample->member) - sample);
> + */
>  #ifdef __GNUC__
>  #define wl_container_of(ptr, sample, member)				\
>  	(__typeof__(sample))((char *)(ptr)	-			\
> -- 
> 1.8.3.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list