c - linux内核宏如何用作函数?

标签 c linux macros kernel kernel-module

这个标题可能听起来很愚蠢,但我以前从未见过这样的东西,我真的不知道该怎么形容它:

所以我刚刚写了我的第一个内核模块,我使用了一个链表,它使用了linux/list.h头文件。其中,有这个宏:

400 /**
401  * list_for_each_entry  -       iterate over list of given type
402  * @pos:        the type * to use as a loop cursor.
403  * @head:       the head for your list.
404  * @member:     the name of the list_struct within the struct.
405  */
406 #define list_for_each_entry(pos, head, member)                          \
407         for (pos = list_entry((head)->next, typeof(*pos), member);      \
408              prefetch(pos->member.next), &pos->member != (head);        \
409              pos = list_entry(pos->member.next, typeof(*pos), member))

而且,我这样使用它(假设 list_head 是列表的头部,list 是结构中的 list_struct) :

struct thing *ptr;
list_for_each_entry(ptr, &list_head, list){
        printk(KERN_INFO "contents: %s\n", ptr->something);
}

当我运行 dmesg 时,列表中的每一项都有一行...

那么,我的问题是:这里发生了什么?我以前从未见过像这样使用宏的函数——编写将以这种方式调用的宏的规则是什么?

我真的不明白为什么会这样,或者我如何编写自己的宏来像这样工作。

最佳答案

宏只是按文本展开。没有魔法发生。您可以使用 gcc -E 查看输出。在这种情况下:

#define list_for_each_entry(pos, head, member)                          \
        for (pos = list_entry((head)->next, typeof(*pos), member);      \
             prefetch(pos->member.next), &pos->member != (head);        \
             pos = list_entry(pos->member.next, typeof(*pos), member))

...

struct thing *ptr;
list_for_each_entry(ptr, &list_head, list){
    printk(KERN_INFO "contents: %s\n", ptr->something);
}

扩展为:

struct thing *ptr;
for (ptr = list_entry((&list_head)->next, typeof(*ptr), list);
     prefetch(ptr->list.next), &ptr->list != (&list_head);
     ptr = list_entry(ptr->list.next, typeof(*ptr), list)) {
    printk(KERN_INFO "contents: %s\n", ptr->something);
}

请注意,我没有在那里做任何艰苦的工作,我只是剪切和粘贴代码并通过 gcc -E(并稍微整理一下格式)。

循环(如您所见)是在扩展代码中完成的。

关于c - linux内核宏如何用作函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21361854/

相关文章:

c - c语言中如何终止程序?

c - 如何提高 Haskell 中这种数值计算的性能?

c - 全局变量和静态变量在 C 中如何协同工作?

c++ - 在 Ubuntu 12.10 上不能包含 "linux/in6.h"而没有错误

c - 处理终止信号

c++ - C/C++ 中的自展开宏循环

c - 我如何只打印出之前在参数中未出现过的字符?

php - 我在多个目录中有一个文件 (foo.php) 的多个副本,我想从一个 PHP 实例中执行这些副本

macros - Clojure 嵌套宏

c - 带有 __va_args__ 和括号的宏错误