不兼容的指针类型 – 为什么?

我试图了解Freebsd中queue(3)宏的内部工作原理。 我之前询问过同一主题的问题,这是一个后续问题。

我试图定义一个函数来插入一个元素到队列中。 queue(3)提供宏STAILQ_INSERT_HEAD ,它需要指向队列头部的指针,队列中项目的类型和要插入的项目。 我的问题是我得到了

 stailq.c:31: warning: passing argument 1 of 'addelement' from incompatible pointer type 

当我尝试将head的地址传递给函数时出错。 完整的源代码如下:

 #include  #include  #include  struct stailq_entry { int value; STAILQ_ENTRY(stailq_entry) entries; }; STAILQ_HEAD(stailhead, stailq_entry); int addelement(struct stailhead *h1, int e){ struct stailq_entry *n1; n1 = malloc(sizeof(struct stailq_entry)); n1->value = e; STAILQ_INSERT_HEAD(h1, n1, entries); return (0); } int main(void) { STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head); struct stailq_entry *n1; unsigned i; STAILQ_INIT(&head); /* Initialize the queue. */ for (i=0;ivalue); free(n1); } return (0); } 

据我所知, headstruct stailhead类型, addelement函数也需要指向struct stailhead的指针。

STAILQ_HEAD(stailhead, stailq_entry); 扩展为:

 struct stailhead { struct stailq_entry *stqh_first; struct stailq_entry **stqh_last; }; 

我在这里想念的是什么?

谢谢。

您只需转换main函数中的第一行即可

 STAILQ_HEAD(stailhead, stailq_entry) head = STAILQ_HEAD_INITIALIZER(head); 

 struct stailhead head = STAILQ_HEAD_INITIALIZER(head); 

发生的事情是STAILQ_HEAD是一个定义新类型的宏,一个结构是您的数据结构,其第一个参数的名称具有第二个参数的条目类型。

您只应调用STAILQ_HEAD一次来定义结构的类型 – 然后从其上使用该类型名称来创建此类型的新数据结构。

您在代码示例中所做的很简单:您定义了一个名为stailhead的结构两次 – 一次在全局范围内,一次在main函数的范围内。 然后,您将指向本地stailhead的指针传递给接受具有相同名称的全局类型的函数。

尽管两个结构都是相同的,但它们位于两个不同的存储范围内,编译器将它们视为不同的类型。 它警告你,你正在从类型main::stailhead转换为类型global::stailhead (注意我刚刚global::stailhead了这个符号,我不相信它是正典)。

您只需要通过在您已经执行的文件顶部调用STAILQ_HEAD宏来定义stailhead ,并从其上使用struct stailhead来定义此类型的对象。