我正在实施双链表。我根据linux kernel list和宏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))
我想知道这些宏的效率如何。我会根据我的结构定义一个新的宏来使用LIST_MEMBER()
,例如:
struct test
{
void *ptr;
t_list lst;
double x;
};
# define TEST_LIST_C2(ptr) LIST_MEMBER(ptr, struct test, list, c2)
我有两个问题:
除了ptr之外的所有内容在编译时都是已知的。我想知道gcc是否会在编译时替换他已经知道的东西,以便我的程序只计算:
*(double*)((char*)ptr + 24)
是否有更有效的方式来访问列表内容?
答案 0 :(得分:1)
如C99 7.17.3中所述,offsetof()是一个宏,因此在编译时进行评估。 typeof()是一个GNU扩展,但它也是一个宏。在编译时(预处理阶段)将宏替换为它们的值。
所以,是的,gcc将在编译时计算所有内容,并以您期望的方式减少表达式。