【问题标题】:efficiently get struct member with macro使用宏有效地获取结构成员
【发布时间】:2016-01-26 08:02:24
【问题描述】:

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

【问题讨论】:

  • 您为什么想知道效率?你发现瓶颈了吗?你有测量数据吗?
  • 一点也不,我只是在寻找好的做法(或者至少,避免低效的可预防代码)。

标签: c gcc macros


【解决方案1】:

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

所以是的,gcc 会在编译时计算它所能做的一切,并以你期望的方式减少表达式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多