2013-06-17 1 views
1

내가 가진 문제는 C 헤더 파일의 순환 종속성 문제입니다. 해결책은 앞으로의 정의와 관련이 있다고 생각하지만 많은 유사한 문제가 있지만typedef 구조체, 순환 종속성, 전달 정의

// fwd1.h 
#ifndef __FWD1_H 
#define __FWD1_H 

#include "fwd2.h" 

typedef 
    struct Fwd1 { 
    Fwd2 *f; 
} 
Fwd1; 

void fwd1 (Fwd1 *f1, Fwd2 *f2) ; 

#endif // __FWD1_H 

: 상장, 아무도 내가이 일을 해결하는 데 필요한 정보 ... 나는 다음과 같은 5 소스 파일이

을 제공하기 위해 보이지 않는다.

// fwd1.c 
#include "fwd1.h" 
#include "fwd2.h" 
void fwd1 (Fwd1 *f1, Fwd2 *f2) { return; } 

.

// fwd2.h 
#ifndef __FWD2_H 
#define __FWD2_H 

#include "fwd1.h" 

typedef 
    struct Fwd2 { 
    Fwd1 *f; 
    } 
Fwd2; 

void fwd2 (Fwd1 *f1, Fwd2 *f2) ; 

#endif // __FWD2_H 

.

// fwd2.c 
#include "fwd1.h" 
#include "fwd2.h" 
void fwd2 (Fwd1 *f1, Fwd2 *f2) { return; } 

. 내가 명령으로 컴파일하고

// fwdMain.c 
#include "fwd1.h" 
#include "fwd2.h" 
int main (int argc, char** argv, char** env) 
{ 
    Fwd1 *f1 = (Fwd1*)0; 
    Fwd2 *f2 = (Fwd2*)0; 

    fwd1(f1, f2); 
    fwd2(f1, f2); 

    return 0; 
} 

: 나는 컴파일 에러를 해결하기 위해 여러 가지 아이디어를 시도,하지만 ... 다른 오류가있는 오류를 대체하기 위해 관리해야 gcc fwdMain.c fwd1.c fwd2.c -o fwd -Wall

는 어떻게 해결합니까 내 코드가 최소한으로 변경되면서 순환 종속성 문제가 발생합니까? ... 이상적으로, 코딩 스타일의 문제로서, 나는 "struct"라는 단어를 제 코드 전체에 두는 것을 피하고 싶습니다.

+0

순환 의존성은 종종 나쁜 생각입니다. Fwd1과 Fwd2를 하나의 구조로 병합 할 수 있습니까? like 'struct Fw {Fw * f1; Fw ** f2;} '? 또 다른 것은 'main()'에서 'f1'과 'f2'를 초기화하지 않았습니다. – Thanushan

+0

@BlueChip 답변으로 불편을 드러내시기 바랍니다. 그런 다음 불편한 점이있는 다른 사람들이 그것이 해결책이라는 것을 알 수 있도록 올바른 것으로 표시하십시오. – cgledezma

+0

@ Thanushan Balakrishnan : 상상할 수 있듯이 _actual_ 문제는이 단순화 된 예제보다 상당히 복잡합니다. 슬프게도 요소를 결합하는 것은 (합리적인) 옵션이 아닙니다 ... @ cgledezma - 전자 메일 옵션을 잘못 설정 한 것 같습니다. – BlueChip

답변

3

여기에서 문제는 순환 형을 수행하면 첫 번째 컴파일러가 실행될 때 gcc가 전체 유형 정의를 갖지 않으므로 (즉, 정의되지 않은 구조 및 내용의 오류가 발생 함) 적절한 위치 적절한 이름 앞에 'struct'라는 단어를 배치해야합니다. 그래서 선언은 다음과 같이 보일 것이다 :

fwd1.h :

//fwd1.h 
#ifndef __FWD1_H 
#define __FWD1_H 

#include "fwd2.h" 

typedef struct Fwd1{ 
    struct Fwd2 *f; 
}Fwd1; 


void fwd1 (Fwd1 *f1, struct Fwd2 *f2) ; 

#endif // __FWD1_H 

fwd2.h :

// fwd2.h 
#ifndef __FWD2_H 
#define __FWD2_H 

#include "fwd1.h" 

typedef struct Fwd2{ 
    struct Fwd1 *f; 
}Fwd2; 

void fwd2 (struct Fwd1 *f1, Fwd2 *f2) ; 

#endif // __FWD2_H 

는이 .c에 함수 정의에 해당하는 변경을 수행합니다. 그것은 매력처럼 작동해야합니다.

P.S : .h 파일의 목적은 .c 파일에 필요한 모든 헤더, 즉 함수 정의, include 등을 선언하는 것입니다. 따라서 .c를 각각의 .h와는 별도로 포함 할 필요는 없습니다.

즉, fwd1.c에는 fwd1.h 만 포함되어야하고 다른 모든 포함은 fwd1.h에 있어야합니다.

+0

다른 솔루션은 또 다른 'typedef struct Fwd2 Fwd2'를 넣는 것입니다. "fwd1.h 및 'typedef struct Fwd1 Fwd1'in fwd2.h. –

+0

또는 각 헤더에 #include 위에 struct 선언을 넣을 수 있습니다. –

0

나는 이것을 테스트하지 못했지만 다음 변형이 효과가있을 것이라고 생각합니다.

// fwd1.h 
#ifndef __FWD1_H 
#define __FWD1_H 

struct Fwd2; // use forward declaration of Fwd2 structure 

typedef 
    struct Fwd1 { 
    Fwd2 *f; 
} 
Fwd1; 

void fwd1 (Fwd1 *f1, Fwd2 *f2) ; 

#endif // __FWD1_H 

// fwd1.c is without changes 

// fwd2.h 
#ifndef __FWD2_H 
#define __FWD2_H 

struct Fwd1; // the same trick 

typedef 
    struct Fwd2 { 
    Fwd1 *f; 
    } 
Fwd2; 

void fwd2 (Fwd1 *f1, Fwd2 *f2) ; 

#endif // __FWD2_H 

// fwd2.c is without changes 

// fwdMain.c is without changes 
+0

슬프게도이 수정이 적용되지 않습니다. – BlueChip

+0

이것은 C++에서 작동합니다 , C에서'struct' 태그는 타입이 아닙니다 (같은 이름으로'typedef'하지 않는 한). – aschepler

0

그냥 fwd1.h의 상단에 추가 :

typedef struct Fwd2 Fwd2; 

지금 당신이 Fwd2* 포인터를 선언하는 예를 들어, 불완전한 유형으로 Fwd2을 사용할 수 있습니다. 마찬가지로, fwd2.h에 당신이 원하는 것 :

typedef struct Fwd1 Fwd1; 

fwd1.h 및 fwd2.h도 서로 #include 할 필요가 없습니다.

+0

@aschelper : 나는 우아한 해결책을 택했습니다. 그러나'main.c'는 컴파일 할 때 이 메소드를 사용하여 _required_ 헤더 (함수 프로토 타입 용)와'typedef' 재 정의를 모두 포함하면 컴파일러가 – BlueChip