【问题标题】:C macro expansion in Linux Kernel codeLinux内核代码中的C宏扩展
【发布时间】:2010-04-20 08:44:49
【问题描述】:

我在编写 C 时通常会忽略使用宏,但我认为我了解宏的基本知识。当我在阅读linux内核中list的源代码时,我看到了类似的东西:

#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

(您可以从here.访问代码的其余部分)

我不明白 LIST_HEAD_INIT 中与符号的功能(我认为它们不是这里的操作数的地址)以及代码中 LIST_HEAD_INIT 的使用。如果有人能启发我,我将不胜感激。

【问题讨论】:

    标签: c linux list macros c-preprocessor


    【解决方案1】:

    要知道实际发生了什么,我们需要 struct list_head 的定义:

    struct list_head {
            struct list_head *next, *prev;
    };
    

    现在考虑宏:

    #define LIST_HEAD_INIT(name) { &(name), &(name) }
    #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
    

    如果在我写的代码中 LIST_HEAD(foo) 它会扩展为:

    struct list_head foo = { &(foo) , &(foo)}
    

    表示一个带有头节点的空双向链表,其中nextprev 指针指向头节点本身。

    和做的一样:

    struct list_head foo;
    foo.next = &foo;
    foo.prev = &foo;
    

    这些宏非常有效地提供了一种初始化双向链表的方法。

    是的,这里使用&作为运营商的地址。

    编辑:

    这是working example

    在您提供的链接中。你有:

    struct list_head test = LIST_HEAD (check);
    

    这是不正确的。你应该有:

    LIST_HEAD (check);
    

    【讨论】:

    • @unicornaddict 在问这个问题之前我考虑了类似的情况。但是在尝试此代码时出现错误:pastebin.com/P2cCfNbQ。我试图给出 void、int、macro 等...并且在这些条件下也出现错误。
    • @holydiver:我已经用 working example 的链接更新了我的答案,并且还指出了 your 代码中的错误。
    • 现在我真的明白了。
    【解决方案2】:

    每当您对宏实际在做什么有疑问时,您可以要求 'gcc -E' 为您扩展它。

    在这种情况下,它只是用指向自身的指针初始化一个列表结构。

    【讨论】:

    • 哇以前不知道这个选项。谢谢
    • 或 cpp -v 使用预处理器
    【解决方案3】:

    这里是地址操作符。内核中的链表避免使用空指针来表示链表的结尾。因此,必须使用一些有效的指针来初始化标头。在这个实现中,如果“头”或“尾”指针指向链表头的地址,则链表被认为是空的。

    【讨论】:

      【解决方案4】:

      list.h 中似乎没有使用宏本身。

      我假设& 确实是代码中的地址。 struct list_head 包含两个指针,因此声明 struct list_head name = LIST_HEAD_INIT(name)(参见宏 LIST_HEAD)应该很自然地获得一对指针作为初始化器。

      【讨论】:

        【解决方案5】:

        它们就是这样,& 符号获取参数的地址并将它们存储在“head”和“next”列表字段中。无法告诉你为什么,因为我没有找到这个宏的实际用途,但它就是这样做的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-20
          • 2015-01-27
          • 2012-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-15
          相关资源
          最近更新 更多