2012-04-06 78 views
2

我想了解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; 
}; 

缺少什麼我在這裏?

謝謝。

+1

它可能與您調用STAILQ_HEAD宏兩次的事實有關,因此重新定義了該結構。不要這樣做。只需將頭部聲明爲所需類型的結構(即「struct stailhead head;」)。這些宏不是名稱空間無效的。 – tbert 2012-04-06 06:08:58

回答

2

你只需要在第一線轉換成你的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來定義此類型的對象。

+0

這是一個清晰而簡潔的解釋!謝謝。 – Raj 2012-04-06 06:16:46

+0

非常歡迎。打開頭文件並查看宏定義通常是進一步瞭解幕後發生的事情和調試宏觀謎團的好方法。 – 2012-04-06 06:32:22