【发布时间】:2014-01-11 06:42:07
【问题描述】:
我正在阅读 linux/list.h 标题,它有 this macro:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
想知道我写LIST_HEAD_INIT(birthday_list)时宏是怎么展开的?
【问题讨论】:
标签: c macros linux-kernel linked-list
我正在阅读 linux/list.h 标题,它有 this macro:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
想知道我写LIST_HEAD_INIT(birthday_list)时宏是怎么展开的?
【问题讨论】:
标签: c macros linux-kernel linked-list
LIST_HEAD_INIT 用于初始化链表头结构实例。
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
来自 linux/types.h:
struct list_head {
struct list_head *next, *prev;
};
这扩展为
struct list_head name = { &(name), &(name) }
如您所见,它已展开,现在结构实例“name”的“prev”和“next”指针字段指向自身。这就是列表头的初始化方式。
初始化后 LIST_HEAD(birthday_list) 是 生日列表.prev = 生日列表.next = &birthday_list “birthday_list”是双链表的头节点,它是空的,而不是让prev和next指针为NULL,它们被设置为指向头节点。
struct list_head birthday_list = {
.next = &birthday_list,
.prev = &birthday_list
}
【讨论】:
& 符号没有什么特别之处,它们只是另一个标记。 LIST_HEAD_INIT(birthday_list) 扩展为 { &(birthday_list), &(birthday_list) }
如果您想自己检查这个或其他宏扩展,您可以直接查看预处理器的输出。 GCC 有 -E 参数来执行此操作。
【讨论】:
{ &(birthday_list), &(birthday_list) }是什么意思吗?
x,&x 计算为内存中x 的位置。