我正在实现双链表。我根据 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)
是否有更有效的方法来访问列表内容?
最佳答案
正如 C99 7.17.3 中所解释的,offsetof() 是一个宏,因此它在编译时进行评估。 typeof() 是一个 GNU 扩展,但它也是一个宏。宏在编译时(预处理阶段)被它们的值替换。
所以,是的,gcc 将在编译时计算它可以计算的所有内容,并按照您期望的方式减少表达式。
关于c - 使用宏有效获取结构成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35009218/