Some compilers have difficulty with the previous implementation which
relies on undefined behavior according to the C standard.  Using
offsetof() from <stddef.h> (which most likely just uses
__builtin_offsetof on modern compilers) allows us to accomplish this
without ambiguity.

Signed-off-by: Jeremy Huddleston Sequoia <[email protected]>
---
 include/list.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/list.h b/include/list.h
index d54a207..ae5431c 100644
--- a/include/list.h
+++ b/include/list.h
@@ -26,6 +26,8 @@
 #ifndef _XORG_LIST_H_
 #define _XORG_LIST_H_
 
+#include <stddef.h> /* offsetof() */
+
 /**
  * @file Classic doubly-link circular list implementation.
  * For real usage examples of the linked list, see the file test/list.c
@@ -232,7 +234,7 @@ xorg_list_is_empty(struct xorg_list *head)
  */
 #ifndef container_of
 #define container_of(ptr, type, member) \
-    (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+    (type *)((char *)(ptr) - (char *) offsetof(type, member))
 #endif
 
 /**
@@ -271,9 +273,9 @@ xorg_list_is_empty(struct xorg_list *head)
 #define xorg_list_last_entry(ptr, type, member) \
     xorg_list_entry((ptr)->prev, type, member)
 
-#define __container_of(ptr, sample, member)                            \
-    (void *)((char *)(ptr)                                             \
-            - ((char *)&(sample)->member - (char *)(sample)))
+#define __container_of(ptr, sample, member)                    \
+    container_of(ptr, typeof(*sample), member)
+
 /**
  * Loop through the list given by head and set pos to struct in the list.
  *
-- 
1.7.11.5

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to