From fce288f6572c135f98cbabd893d0d93d1ff5a244 Mon Sep 17 00:00:00 2001 From: Przemyslaw Pawelczyk Date: Sat, 5 Jul 2014 00:31:04 +0200 Subject: [PATCH 1/3] Rewrite container_of macro without using statement expression. Statement expression is GNU C extension, not present in ISO standard. Type checking works now via implicit conversion performed for compound literal (compound literals are available since C99). typeof is only used on GNUC compilers like gcc or clang. --- utils.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/utils.h b/utils.h index c2277e9..991af9c 100644 --- a/utils.h +++ b/utils.h @@ -20,6 +20,12 @@ struct sockaddr_in; #endif +#ifdef __GNUC__ +#define member_type(type, member) __typeof(((type *)0)->member) +#else +#define member_type(type, member) const void +#endif + /** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. @@ -27,9 +33,11 @@ struct sockaddr_in; * @member: the name of the member within the struct. * */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#define container_of(ptr, type, member) \ + ((type *)( \ + (char *)(member_type(type, member) *){ ptr } - offsetof(type, member) \ + )) + #define clamp_value(value, min_val, max_val) do { \ if (value < min_val) \ From 19f0fb225a9db5c6913e735adbfa706e2e6a5b34 Mon Sep 17 00:00:00 2001 From: Przemyslaw Pawelczyk Date: Sat, 5 Jul 2014 01:11:34 +0200 Subject: [PATCH 2/3] Use __typeof instead of typeof. __typeof adheres to ISO C standard as it is reserved identifier [1], so it is collision-free and works in non-GNU mode as long as compiler supports it. [1] C99: "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use." --- list.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/list.h b/list.h index 9db4c4f..8200a16 100644 --- a/list.h +++ b/list.h @@ -300,9 +300,9 @@ static inline void list_splice_init(struct list_head_t *list, * @member: the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + pos = list_entry(pos->member.next, __typeof(*pos), member)) /** * list_for_each_entry_reverse - iterate backwards over list of given type. @@ -311,9 +311,9 @@ static inline void list_splice_init(struct list_head_t *list, * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ + for (pos = list_entry((head)->prev, __typeof(*pos), member); \ &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) + pos = list_entry(pos->member.prev, __typeof(*pos), member)) /** * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue @@ -324,7 +324,7 @@ static inline void list_splice_init(struct list_head_t *list, * Prepares a pos entry for use as a start point in list_for_each_entry_continue. */ #define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) + ((pos) ? : list_entry(head, __typeof(*pos), member)) /** * list_for_each_entry_continue - continue iteration over list of given type @@ -336,9 +336,9 @@ static inline void list_splice_init(struct list_head_t *list, * the current position. */ #define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ + for (pos = list_entry(pos->member.next, __typeof(*pos), member); \ &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + pos = list_entry(pos->member.next, __typeof(*pos), member)) /** * list_for_each_entry_from - iterate over list of given type from the current point @@ -350,7 +350,7 @@ static inline void list_splice_init(struct list_head_t *list, */ #define list_for_each_entry_from(pos, head, member) \ for (; &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + pos = list_entry(pos->member.next, __typeof(*pos), member)) /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry @@ -360,10 +360,10 @@ static inline void list_splice_init(struct list_head_t *list, * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ + for (pos = list_entry((head)->next, __typeof(*pos), member), \ + n = list_entry(pos->member.next, __typeof(*pos), member); \ &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) + pos = n, n = list_entry(n->member.next, __typeof(*n), member)) /** * list_for_each_entry_safe_continue @@ -376,10 +376,10 @@ static inline void list_splice_init(struct list_head_t *list, * safe against removal of list entry. */ #define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ + for (pos = list_entry(pos->member.next, __typeof(*pos), member), \ + n = list_entry(pos->member.next, __typeof(*pos), member); \ &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) + pos = n, n = list_entry(n->member.next, __typeof(*n), member)) /** * list_for_each_entry_safe_from @@ -392,9 +392,9 @@ static inline void list_splice_init(struct list_head_t *list, * removal of list entry. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ + for (n = list_entry(pos->member.next, __typeof(*pos), member); \ &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) + pos = n, n = list_entry(n->member.next, __typeof(*n), member)) /** * list_for_each_entry_safe_reverse @@ -407,9 +407,9 @@ static inline void list_splice_init(struct list_head_t *list, * of list entry. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ + for (pos = list_entry((head)->prev, __typeof(*pos), member), \ + n = list_entry(pos->member.prev, __typeof(*pos), member); \ &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) + pos = n, n = list_entry(n->member.prev, __typeof(*n), member)) #endif From a7d1fb09a094f4bc19627101337d88eedbe25cf8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Pawelczyk Date: Sat, 5 Jul 2014 01:28:44 +0200 Subject: [PATCH 3/3] Switch from gnu99 to C99 and provide proper feature macros. Use _XOPEN_SOURCE=600 to make system headers expose Single UNIX Specification v3 (SUSv3) definitions, i.e. POSIX.1-2001 base specification plus the X/Open System Interface (XSI) extension. POSIX.1-2001 is aligned with C99, so that all of the library functions standardized in C99 are also standardized in POSIX.1-2001. Use _BSD_SOURCE together with _DEFAULT_SOURCE to compile without warnings in glibc <= 2.19 and glibc >= 2.20 (_BSD_SOURCE is deprecated since glibc 2.20 and it has same effect as defining _DEFAULT_SOURCE but generates a compile-time warning if used alone). This is required for availability of non-POSIX functions, like inet_aton() or timercmp(), that are present on most BSD derivatives. Note: _DEFAULT_SOURCE, which was introduced in glibc 2.19, will actually bump _POSIX_C_SOURCE from 200112L to 200809L, but it brings no harm. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4b83c13..dd32077 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ VERSION := 0.4 LIBS := -levent CFLAGS += -g -O2 -override CFLAGS += -std=gnu99 -Wall +override CFLAGS += -std=c99 -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -Wall all: $(OUT)