From 578da7e7b6265153fa0519035fc52a086a711ac0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 12 Dec 2011 13:50:05 +1030 Subject: [PATCH 1/1] container_of: don't put member_ptr in container_off. It's convenient to check that the member is the given type, but we can leave that to the callers. --- ccan/container_of/container_of.h | 26 ++++++++++++-------------- ccan/container_of/test/run.c | 4 ++-- ccan/list/list.h | 11 +++++++++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/ccan/container_of/container_of.h b/ccan/container_of/container_of.h index 4490184c..ea8f1dd3 100644 --- a/ccan/container_of/container_of.h +++ b/ccan/container_of/container_of.h @@ -32,19 +32,17 @@ #define container_of(member_ptr, containing_type, member) \ ((containing_type *) \ ((char *)(member_ptr) \ - - container_off((member_ptr), containing_type, member))) + - container_off(containing_type, member)) \ + + check_types_match(*(member_ptr), ((containing_type *)0)->member)) /** * container_off - get offset to enclosing structure - * @member_ptr: pointer to the structure member * @containing_type: the type this member is within * @member: the name of this member within the structure. * * Given a pointer to a member of a structure, this macro does * typechecking and figures out the offset to the enclosing type. * - * Note that @member_ptr is not evaluated. - * * Example: * struct foo { * int fielda, fieldb; @@ -57,18 +55,17 @@ * * static struct info *foo_to_info(struct foo *foo) * { - * size_t off = container_off(foo, struct info, my_foo); + * size_t off = container_off(struct info, my_foo); * return (void *)((char *)foo - off); * } */ -#define container_off(member_ptr, containing_type, member) \ - (offsetof(containing_type, member) \ - + check_types_match(*(member_ptr), ((containing_type *)0)->member)) +#define container_off(containing_type, member) \ + offsetof(containing_type, member) /** * container_of_var - get pointer to enclosing structure using a variable * @member_ptr: pointer to the structure member - * @var: a pointer to a structure of same type as this member is within + * @container_var: a pointer of same type as this member's container * @member: the name of this member within the structure. * * Given a pointer to a member of a structure, this macro does pointer @@ -82,12 +79,13 @@ * } */ #if HAVE_TYPEOF -#define container_of_var(member_ptr, var, member) \ - container_of(member_ptr, typeof(*var), member) +#define container_of_var(member_ptr, container_var, member) \ + container_of(member_ptr, typeof(*container_var), member) #else -#define container_of_var(member_ptr, var, member) \ - ((void *)((char *)(member_ptr) \ - - ((char *)&(var)->member - (char *)(var)))) +#define container_of_var(member_ptr, container_var, member) \ + ((void *)((char *)(member_ptr) \ + - ((char *)&(container_var)->member \ + - (char *)(container_var)))) #endif #endif /* CCAN_CONTAINER_OF_H */ diff --git a/ccan/container_of/test/run.c b/ccan/container_of/test/run.c index 8f86bc8d..96ef483c 100644 --- a/ccan/container_of/test/run.c +++ b/ccan/container_of/test/run.c @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) ok1(container_of_var(intp, &foo, a) == &foo); ok1(container_of_var(charp, &foo, b) == &foo); - ok1(container_off(intp, struct foo, a) == 0); - ok1(container_off(charp, struct foo, b) == offsetof(struct foo, b)); + ok1(container_off(struct foo, a) == 0); + ok1(container_off(struct foo, b) == offsetof(struct foo, b)); return exit_status(); } diff --git a/ccan/list/list.h b/ccan/list/list.h index 1feb5891..5c9aa2a6 100644 --- a/ccan/list/list.h +++ b/ccan/list/list.h @@ -4,6 +4,7 @@ #include #include #include +#include /** * struct list_node - an entry in a doubly-linked list @@ -280,7 +281,7 @@ static inline void list_del_from(struct list_head *h, struct list_node *n) * first = list_top(&parent->children, struct child, list); */ #define list_top(h, type, member) \ - ((type *)list_top_((h), container_off((h)->n.next, type, member))) + ((type *)list_top_((h), list_off_(type, member))) static inline const void *list_top_(const struct list_head *h, size_t off) { @@ -302,7 +303,7 @@ static inline const void *list_top_(const struct list_head *h, size_t off) * last = list_tail(&parent->children, struct child, list); */ #define list_tail(h, type, member) \ - ((type *)list_tail_((h), container_off((h)->n.next, type, member))) + ((type *)list_tail_((h), list_off_(type, member))) static inline const void *list_tail_(const struct list_head *h, size_t off) { @@ -370,4 +371,10 @@ static inline const void *list_tail_(const struct list_head *h, size_t off) nxt = container_of_var(i->member.next, i, member); \ &i->member != &(h)->n; \ i = nxt, nxt = container_of_var(i->member.next, i, member)) + +/* Get the offset of the member, but make sure it's a list_node. */ +#define list_off_(type, member) \ + (container_off(type, member) + \ + check_type(((type *)0)->member, struct list_node)) + #endif /* CCAN_LIST_H */ -- 2.39.2