2012-04-06 5 views
2

Freebsd에서 queue (3) 매크로의 내부 동작을 이해하려고합니다. 나는 이전에 question에 대해 같은 주제에 대해 물어 보았습니다. 그리고 이것에 대한 후속 질문입니다.호환되지 않는 포인터 유형 - 이유가 무엇입니까?

대기열에 요소를 삽입하는 함수를 정의하려고합니다. queue (3)은 큐 머리글, 큐에있는 항목의 유형 및 삽입 할 항목에 대한 포인터가 필요한 매크로 STAILQ_INSERT_HEAD을 제공합니다. 내 문제는 내가 함수에 head의 주소를 통과 할 때 나는

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

오류가 발생하고 있다는 점이다.

#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); 
} 

를 지금까지 내가 말할 수있는 head 유형 struct stailhead의하고 addelement 기능은 struct stailhead에 대한 포인터를 기대하고, 다음과 같이 전체 소스 코드입니다. 내가 여기 실종 무엇

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

:

STAILQ_HEAD(stailhead, stailq_entry);는로 확장?

감사합니다. 무엇 일어나는 것은 STAILQ_HEAD 새로운 유형을 정의하는 매크로는 점이다

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

struct stailhead head = STAILQ_HEAD_INITIALIZER(head); 

+1

이것은 STAILQ_HEAD 매크로를 두 번 호출하여 구조체를 재정의한다는 것과 관련이있을 수 있습니다. 그러지 마. 헤드를 원하는 유형의 구조체로 선언하면됩니다 (예 : "stailhead head 구조체"). 이 매크로는 네임 스페이스 - 효과가 없습니다. – tbert

답변

2

당신은,에서 main 기능의 첫 번째 라인을 변환하는 것입니다 구조체가 필요합니다 두 x 째 매개 변수의 입력 유형이있는 첫 x 째 매개 변수의 이름으로 데이터 구조.

구조체의 유형을 정의하기 위해 한 번만 호출해야합니다. 그런 다음이 유형의 새 데이터 구조를 만들 때 그 형식 이름을 사용합니다.

코드 샘플에서 수행 한 작업은 간단합니다. stailhead이라는 구조체를 전역 범위에서 한 번, main 함수의 범위에서 한 번 두 번 정의했습니다. 그런 다음 로컬 이름 stailhead에 대한 포인터를 같은 이름의 전역 유형을 허용하는 함수에 전달했습니다.

두 구조체가 모두 동일하더라도 두 가지 다른 저장소 범위에 있으며 컴파일러는이 구조체를 별개의 형식으로 처리합니다. main::stailhead 유형을 global::stailhead 유형으로 변환하고 있음을 경고합니다 (이 표기법을 작성했지만 캐논이라고 생각하지 않습니다).

이미 수행 한 파일의 상단에서 STAILQ_HEAD 매크로를 한 번만 호출하면 stailhead을 정의하고이 매크로에서 struct stailhead을 사용하여이 유형의 개체를 정의하면됩니다.

+0

이것은 명확하고 간결한 설명입니다! 감사. – Raj

+0

당신을 가장 환영합니다.헤더 파일을 열고 매크로 정의를 보면 대개 무대 뒤에서 일어나는 일과 매크로 신비를 디버그하는 데 더 좋은 방법입니다. –

관련 문제