Reputation: 1397
I am implementing double linked list. I produce the following macro, based on linux kernel list and the macro container_of:
typedef struct s_list
{
struct s_list *prev;
struct s_list *next;
} t_list;
# define LIST_ENTRY(ptr, type, lst_member) \
(type*)((char*)ptr - offsetof(type, lst_member))
# define LIST_MEMBER(ptr, type, lst_member, member) \
*(typeof(&(((type*)0)->member))) \
(LIST_ENTRY(ptr, type, lst_member) + offsetof(type, member))
I wonder how efficient are those macro. I would use LIST_MEMBER()
by defining a new macro depending on my struct, for instance, for instance:
struct test
{
void *ptr;
t_list lst;
double x;
};
# define TEST_LIST_C2(ptr) LIST_MEMBER(ptr, struct test, list, c2)
I have two questions:
Everything except ptr is known at compile time. I would like to know if gcc would replace at compile time what he already knows so that my program just compute:
*(double*)((char*)ptr + 24)
Is there a more efficient way to access list content ?
Upvotes: 0
Views: 121
Reputation: 1405
As explained in C99 7.17.3 offsetof() is a macro, so it's evaluated at compile time. typeof() is a GNU extension, but it's also a macro. Macros are replaced with their values at compile time (the preprocessing phase).
So yes, gcc will compute everything it can at compile time and reduce the expression the way you expect.
Upvotes: 1