c编程#define struct {}声明

时间:2017-02-01 15:26:44

标签: c glibc

我在看Glibc代码。一些glibc队列的代码引起了我的注意。我无法给出这个结构定义的含义。此结构没有名称。为什么?它是如何工作的?

#define LIST_ENTRY(type)                        \
struct {                                \
    struct type *le_next;   /* next element */          \
    struct type **le_prev;  /* address of previous next element */  \
}

Source

2 个答案:

答案 0 :(得分:9)

这实际上是一个预处理器宏,可以在其他地方扩展(最有可能是尾随名称)。

在该头文件开头的注释中有一个对queue(3) man page的引用,其中包含有关该头文件和其他宏的更多详细信息:

  

宏LIST_ENTRY声明了一个连接元素的结构   在列表中。

使用的一个例子:

var myExample2 = new Example2();

作为这个C代码(不是C ++),而C缺少模板,这个预处理器宏可以用来“模拟”模板(注意LIST_HEAD(listhead, entry) head = LIST_HEAD_INITIALIZER(head); struct listhead *headp; /* List head. */ struct entry { ... LIST_ENTRY(entry) entries; /* List. */ ... } *n1, *n2, *n3, *np, *np_temp; LIST_INIT(&head); /* Initialize the list. */ n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ LIST_INSERT_HEAD(&head, n1, entries); 参数)。

答案 1 :(得分:8)

它是一个用于声明结构类型的宏,其中nextprev指针指向第二个结构类型的实例。第二种类型可以是父类型,因此您可以创建一个"可链接的结构"像这样:

struct foo {
  LIST_ENTRY(foo) list;
  int value;
};

这会创建一个struct foo,其中包含一个名为list的成员,而该成员又是问题中的结构,指针指向struct foo

我们现在可以创建一个struct foo的小链表,如下所示:

struct foo fa, fb;
fa.value = 47;
fa.list.le_next = &fb;
fa.list.le_prev = NULL;
fb.value = 11;
fb.list.le_next = NULL;
fb.list.le_prev = &fa.list.le_next;

我对最后一行不是100%肯定,但我认为这是有道理的。