Linux 内核代码中的 C 宏扩展
我在用C编写时通常会忽略宏的使用,但我认为我了解它们的基础知识。当我阅读linux内核中list的源代码时,我看到了类似的东西:(
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
您可以从 此处。)
我不理解LIST_HEAD_INIT中与号的功能(我不认为它们是操作数的地址)以及代码中LIST_HEAD_INIT的使用。如果有人能启发我,我将不胜感激。
I generally have ignored using macros while writing in C but I think I know fundamentals about them. While I was reading the source code of list in linux kernel, I saw something like that:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
(You can access the remaining part of the code from here.)
I didn't understand the function of ampersands(I don't think they are the address of operands here) in LIST_HEAD_INIT and so the use of LIST_HEAD_INIT in the code. I'd appreciate if someone can enlighten me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
要了解实际发生的情况,我们需要
struct list_head
的定义:现在考虑宏:
如果在代码中我编写
LIST_HEAD(foo)
它会扩展为:带有标头节点的空双向链表,其中
next
和prev
指针指向标头节点本身。它与这样做相同:
因此,这些宏有效地提供了一种初始化双向链表的方法。
是的,这里使用
&
作为运算符的地址。编辑:
这是一个
工作示例
您提供的链接。你有:
这是不正确的。你应该有:
To know what actually is happening we need the definition of
struct list_head
:Now consider the macros:
If in the code I write
LIST_HEAD(foo)
it gets expanded to:which represents an empty doubly linked list with a header node where the
next
andprev
pointers point to the header node itself.It is same as doing:
So effectively these macros provide a way to initialize a doubly linked list.
And yes,
&
is used here as the address of operator.EDIT:
Here is a
working example
In the link provided by you. You had:
which is incorrect. You should have:
每当您对宏实际上在做什么有疑问时,您可以要求“gcc -E”为您扩展它。
在这种情况下,它只是用指向自身的指针初始化一个列表结构。
Every time you're in doubt on what macro is actually doing, you can ask 'gcc -E' to expand it for you.
In this case it just initialise a list structure with pointers to itself.
他们在这里是地址运算符。内核中的链表避免使用空指针来表示列表的末尾。因此,必须使用一些有效的指针来初始化标头。在此实现中,如果“头”或“尾”指针指向列表头的地址,则该列表被认为是空的。
They are address-of operators here. The linked lists in the kernel avoid null pointers to denote the end of a list. Therefore, the header must be initialized with some valid pointer. In this implementation, if the "head" or "tail" pointer point to the address of the list header, the list is considered empty.
list.h
中似乎没有使用宏本身。我假设
&
确实意味着代码中的地址。struct list_head
包含两个指针,因此声明struct list_head name = LIST_HEAD_INIT(name)
(参见宏LIST_HEAD
)应该很自然获取一对指针作为初始值设定项。The macro itself seems to be not used in the
list.h
.I assume
&
mean indeed addresses in the code. Thestruct list_head
contains two pointers, so it should be quite natural for declarationstruct list_head name = LIST_HEAD_INIT(name)
(see macroLIST_HEAD
) to obtain a pair of pointers as initializer.这正是它们的本质,& 符号获取参数的地址并将它们存储在“head”和“next”列表字段中。无法告诉你为什么,因为我没有找到这个宏的实际用途,但这就是它的作用。
That's exactly what they are, the ampersands take the address of the parameter and store them in both in the "head" and "next" list fields. Couldn't tell you why, since I didn't find an actual use of this macro, but that's what it does.