使用宏有效地获取struct成员

时间:2016-01-26 08:02:25

标签: c gcc macros

我正在实施双链表。我根据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)
    
  • 是否有更有效的方式来访问列表内容?

1 个答案:

答案 0 :(得分:1)

如C99 7.17.3中所述,offsetof()是一个宏,因此在编译时进行评估。 typeof()是一个GNU扩展,但它也是一个宏。在编译时(预处理阶段)将宏替换为它们的值。

所以,是的,gcc将在编译时计算所有内容,并以您期望的方式减少表达式。