【问题标题】:incompatible pointer type - why?不兼容的指针类型 - 为什么?
【发布时间】:2012-04-06 05:49:04
【问题描述】:

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

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>

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;i<10;i++){
                addelement(&head, i);
        }
        n1 = NULL;

        while (!STAILQ_EMPTY(&head)) {
                n1 = STAILQ_LAST(&head, stailq_entry, entries);
                STAILQ_REMOVE(&head, n1, stailq_entry, entries);
                printf ("n2: %d\n", n1->value);
                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; 
};

我在这里错过了什么?

谢谢。

【问题讨论】:

  • 这可能与您两次调用 STAILQ_HEAD 宏的事实有关,从而重新定义了结构。不要那样做。只需将 head 声明为所需类型的结构(即“struct stailhead head;”)。这些宏不是没有命名空间副作用的。

标签: c


【解决方案1】:

您只需将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(请注意,我只是编造了这个符号,我不相信它是佳能)。

您只需在文件顶部调用一次STAILQ_HEAD 宏即可定义stailhead,然后使用struct stailhead 定义此类型的对象。

【讨论】:

  • 不客气。打开头文件并查看宏定义通常是进一步了解幕后发生的事情和调试宏奥秘的好方法。
猜你喜欢
  • 2011-04-09
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 2017-12-14
  • 2012-02-07
  • 1970-01-01
相关资源
最近更新 更多